.as_null_object на двойнике заставляет Rspec просто висеть? - PullRequest
1 голос
/ 17 января 2012

Я не совсем уверен, как это объяснить.

У меня есть приложение Rails 3.1.3, работающее под управлением RSpec 2.8.1, с набором тестов из 284 тестов. Они будут казаться снова и снова довольно счастливо.

Я добавил новый тест сегодня, для пользователя, обновляющего свои настройки -

require 'spec_helper'

describe UserSettingsController do

  describe 'PUT "update"' do

    let!(:user) { Fabricate :user }

    it 'updates the User with the correct attributes' do
      proxy = double('proxy')   #.as_null_object
      controller.should_receive(:current_user).any_number_of_times { proxy }

      attributes = Fabricate(:user_settings).stringify_keys
      proxy.should_receive(:update_attributes).with(attributes, :as => :updater) { true }

      login_user(user)
      put :update, :user => attributes
    end

  end

end

Первоначально этот тест не пройден, потому что у меня в файле application_controller.rb before_filter, который также ссылается на current_user (который вызывает непредвиденное сообщение на макете), поэтому я решил сделать макет пустым объектом (см. Закомментированную область выше).

Когда я делаю это, хотя ... весь набор тестов просто зависает, как будто в бесконечном цикле, после завершения теста (но до перехода к следующему).

Кто-нибудь видел что-нибудь подобное раньше? Я неправильно использую .as_null_object?

edit: , чтобы прояснить некоторые моменты, login_user является вспомогательным средством, предоставляемым Sorcery для аутентификации в тестах, а производитель :user_settings просто создает хеш с часовым поясом в нем.

1 Ответ

1 голос
/ 18 января 2012

Если только вы :user_settings фабрика не ссылаетесь на себя, я бы посмотрел на две вещи. Первый:

describe UserSettingsController do

  describe 'PUT "update"' do
    let(:proxy) { double('proxy').as_null_object }
    let(:user) { Fabricate :user }

    before(:each) do
      login_user(user)
    end

    it 'updates the User with the correct attributes' do
      controller.should_receive(:current_user).any_number_of_times { proxy }

      attributes = Fabricate(:user_settings).stringify_keys
      proxy.should_receive(:update_attributes).with(attributes, :as => :updater) { true }

      put :update, :user => attributes
    end

  end

end

Если это не так, как раньше, вы знаете, что проблема где-то внутри колдовства. (Вы никогда не увидите пример вывода итоговой строки в своей консоли.) Обратите внимание, что я сохранил вызов #as_null_object: колдовство будет подталкивать смоделированного пользователя к информации, в основном заполняя хэши. Начните читать здесь , если вам интересно. Если , что не поможет точно определить проблему, рассмотрите возможность полного удаления login_user. Вот так:

describe UserSettingsController do

  describe 'PUT "update"' do
    let(:proxy) { double('proxy') }
    let(:user) { Fabricate :user }

    it 'updates the User with the correct attributes' do
      controller.should_receive(:current_user).any_number_of_times { proxy }

      attributes = Fabricate(:user_settings).stringify_keys
      proxy.should_receive(:update_attributes).with(attributes, :as => :updater) { true }

      put :update, :user => attributes
    end

  end

end

Вы заглушаете current_user, чтобы быть определенным контроллером, который, как я думаю, будет , будет означать, что вы пропустите свой хук before_filter auth, определив current_user как proxy. Если во всех вызовах происходит что-то глупое, вы, по крайней мере, сокращаете их количество.

Я все еще догадываюсь - я не создавал пример приложения. Удачи.

...