Сложность отладки RSepec - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь отладить свою спецификацию функции в RSpec. Но я не могу получить исключение. Если я поставлю binding.pry перед auth.save!, я смогу взломать. Затем я проверяю, если auth.valid?, и он возвращает true. Я также называю auth.save вручную без исключения. Но если я поставлю монету после user.update_for_omniauth omniauth, она не попадет. Метод update_from_omniauth на самом деле не вызывается, потому что я его заглушаю. В конце моего метода есть спасательный блок. Помещение подглядывания там тоже ничего не вызывает. Моя спецификация не работает, потому что я не нашел ни аутентификации, ни пользователя в базе данных.

контроллер аутентификации

def create
    user   = merge_users! if current_user
    auth   = current_auth
    user ||= auth&.user

    email_user = User.has_email.where(email: omniauth.info.email).first_or_initialize
    if user && email_user.persisted? && user != email_user
      user.merge! email_user, auth
    end
    user ||= email_user

    auth ||= user.authentications.build uid: omniauth.uid,
      provider: omniauth.provider, image_url: omniauth.info.image
    auth.token = omniauth.credentials.token

    if Authentication::GOOGLE.include?(params[:provider].to_sym)
      auth.token_expire = Time.at(omniauth.credentials.expires_at)
    end

    if omniauth.credentials.refresh_token
      auth.refresh_token = omniauth.credentials.refresh_token
    end

    auth.refresh_facebook_token # get a longer running token
    auth.save!

    user.update_for_omniauth omniauth
    user.save!

    if params[:provider] == 'google_contacts'
      params[:sync_status] = Contact.sync player, auth.token
    end
    sign_in_and_redirect user
  rescue => e
    if Rails.env.production?
      Raven.capture_exception e, extra: omniauth
      redirect_back fallback_location: new_user_session_path, flash: {error: e.message}
    else
      raise
    end

версия спецификации 1

   it 'set organically login user as propertyuser' do
      visit '/users/sign_in'
      click_link 'Login via Facebook'
      expect(Authentication.last.uid).to eq('654321')
    end

спецификация версии 2

    it 'set organically login user as propertyuser' do
      visit '/users/sign_in'
      click_link 'Login via Facebook'
      expect(User.last.email).to eq('facebookuser@mail.com')
    end

больше спецификаций

    before do
      setup_omniauth
      application_controller_patch
      allow(Facebook).to receive_message_chain(:oauth_for_app, :exchange_access_token_info).and_return('access_token' => '123', 'expires' => 500_000)
      allow_any_instance_of(Authentication).to receive(:refresh_facebook_token) #.and_return(true)
      allow_any_instance_of(User).to receive(:update_facebook_properties)# .and_return(true)
      allow_any_instance_of(User).to receive(:update_for_omniauth)# .and_return(true)
    end

  def setup_omniauth
    OmniAuth.config.test_mode = true
    OmniAuth.config.mock_auth[:facebook_app_rewards] = OmniAuth::AuthHash.new(
      'provider' => 'facebook',
      'uid' => '654321',
      'info' => {
        'first_name' => 'Facebook',
        'last_name' => 'User',
        'email' => 'facebookuser@mail.com',
        'image' => 'https://randomuser.me/api/portraits/med/men/65.jpg'
      },
      'credentials' => {
        'token' => '123456',
        'secret' => 'top_secret',
        'expires_at' => 2.days.from_now
      }
    )
    Rails.application.env_config['devise.mapping'] = Devise.mappings[:user]
    Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[:facebook_app_rewards]
  end

  def application_controller_patch
    ApplicationController.class_eval do
      def omniauth
        Rails.application.env_config['omniauth.auth']
      end
    end
  end

1 Ответ

1 голос
/ 02 мая 2019

Наиболее вероятная причина, по которой ваши тесты не пройдены, заключается в том, что действия, вызванные click_link, не гарантированно завершатся при возврате click_link.Вы можете проверить это, добавив несколько секунд sleep после click_link.Если это исправит ваш тест, то вы можете заменить sleep на ожидаемое визуальное изменение на странице.

click_link 'Login via Facebook'
expect(page).to have_text('You have logged in!') # expectation for whatever happens on the page after a successful login
expect ...  # rest of your test.

Примечание.плохая идея (насмешка над чем-либо, кроме внешних служб, как правило, является неприятным запахом кода в тесте функций), так же как и прямой доступ к БД из тестов функций.Функциональные тесты предназначены для тестирования всего, что пользователь испытывает на сайте, а не для непосредственного тестирования деталей реализации.

...