0

На моей странице регистрации devise я реализовал функцию отслеживания ip, которая, когда пользователь подписывается, отправляет страну пользователь приходит, чтобы заполнить атрибут вновь созданной учетной записи 'user_country'Проверка Rspec для проверки пользователя получает заполненный заполненный атрибут ip_location (Rails 4/devise/geocoder)

Это работает, но как новичок Я не знаю, как проверить с помощью rspec, что это работает, т.е. если я создаю пользователя, который подписывает а затем ПОСЛЕ создания учетной записи, то user_country больше не пуст.

Вот как я использую метод /app/controllers/registrations_controller.rb назначить страну для вновь созданного accoun пользователя на контроллерах/registrations_controller.rb- см ниже

class RegistrationsController < Devise::RegistrationsController 

    layout 'lightbox' 

    def update  
    account_update_params = devise_parameter_sanitizer.sanitize(:account_update) 

    # required for settings form to submit when password is left blank 
    if account_update_params[:password].blank? 
     account_update_params.delete("password") 
     account_update_params.delete("password_confirmation") 
    end  
    @user = User.find(current_user.id) 
    if @user.update(account_update_params) # Rails 4 .update introduced with same effect as .update_attributes 
     set_flash_message :notice, :updated 
     # Sign in the user bypassing validation in case his password changed 
     sign_in @user, :bypass => true 
     redirect_to after_update_path_for(@user) 
    else 
     render "edit" 
    end 
    end 

    # for Rails 4 Strong Parameters 
    def resource_params 
    params.require(:user).permit(:email, :password, :password_confirmation, :current_password, :user_country) 
    end 
    private :resource_params 

    protected 
    def after_sign_up_path_for(resource) 
     resource.update(user_country: set_location_by_ip_lookup.country) #use concerns/CountrySetter loaded by ApplicationController 
     root_path 
    end 

end 

Если это помогает, это как я нахожу страну посетителя:

module CountrySetter 

    extend ActiveSupport::Concern 

    included do 
     before_filter :set_location_by_ip_lookup 
    end 

    # we use geocoder gem 
    # output: ip address 
    def set_location_by_ip_lookup 
     if Rails.env.development? or Rails.env.test? 
     Geocoder.search(request.remote_ip).first 
     else 
     request.location 
     end 
    end 
end 
+1

Я вижу, что вы делаете 'if Rails.env.development? или Rails.env.test? '. Будьте предельно осторожны при использовании литералов '' '' '' 'или' в Ruby, потому что они предназначены для использования в потоке управления, а не в булевых выражениях. Использование их без понимания их побочных эффектов может вызвать серьезные проблемы, такие как выражение всегда возвращает true. – rickypai

+0

также 'и' 'или' имеют более низкий порядок работы, чем '&&' '||' http://www.techotopia.com/index.php/Ruby_Operator_Precedence – rickypai

+0

спасибо за эти советы: я буду осторожен и попытаюсь понять разницу между AND vs && + Or vs || => как новичок Rails, я думал, что это в основном то же самое :) Я проверю это – Mathieu

ответ

1

Вам необходимо использовать парные очки в вашем тесте.

describe UserController do 
    it 'sets the request location with Geocoder' do 
    geocoder = class_double("Geocoder") # class double 
    location = double('location', country: 'some country') # basic double with return values 
    expect(geocoder).to receive(:search).and_return(location) # stubbing return value 

    post :create, user_params 

    user = assigns(:user) 
    expect(user.user_country).to eq('some country') 
    end 
end 

Таким образом, мы создаем поддельное местоположение и геокодер, а также создаем фальшивые возвращаемые значения. то мы утверждаем, что возвращаемое значение из геокодера сохраняется в качестве атрибута пользователя. таким образом, нам действительно не нужно проверять, работает ли Geocoder, и упрощает нашу тестовую настройку.

понятия используются здесь:

https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/basics/test-doubles https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/verifying-doubles/using-a-class-double https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/configuring-responses/returning-a-value

, если Вы хотите быть более надежными, вы можете быть в состоянии подделать адрес внутрибрюшинно в контексте запроса теста, а затем утверждать, какие аргументы поддельные геокодер получает с аргументом соответствия: https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/setting-constraints/matching-arguments

В общем, вы должны использовать mocks, чтобы изолировать проблемы ваших тестов. см. https://relishapp.com/rspec/rspec-mocks/v/3-0/docs для дополнительной документации

+0

спасибо, но когда я это делаю в rspec/controllers Usercontroller, как было предложено, я получаю эту ошибку: Ошибка/Ошибка: post: create, user_params NameError: Неопределенная локальная переменная или метод 'user_params 'для # . Вы знаете, почему? btw я использую Devise для пользователя creaiton с подтверждением электронной почты/пароля/пароля (так что у меня есть контроллеры/регистраторыКонтроллеры и все ...) – Mathieu

+0

мой код не является полным. вам нужно заполнить 'user_params' любым параметром, необходимым для создания пользователя. Я предполагаю, что это, по крайней мере, имя пользователя/адрес электронной почты и пароль – rickypai

+0

hzaha ok, извините за вопрос новичков :). я использую фабричную девушку, поэтому я создам пользователя с ней – Mathieu