Pergunta

Eu quero ter certeza que meu varredor está sendo chamado como apropriado, então eu tentei adicionar algo como isto:

it "should clear the cache" do
    @foo = Foo.new(@create_params)
    Foo.should_receive(:new).with(@create_params).and_return(@foo)
    FooSweeper.should_receive(:after_save).with(@foo)
    post :create, @create_params
end

Mas eu fico:

<FooSweeper (class)> expected :after_save with (...) once, but received it 0 times

Eu tentei ligar cache na configuração de teste, mas isso não faz qualquer diferença.

Foi útil?

Solução

Como você já caching mencionado tem que ser ativado no ambiente para que isso funcione. Se for desativado, em seguida, o meu exemplo a seguir irá falhar. É provavelmente uma boa idéia para activar esta temporariamente em tempo de execução para suas especificações de armazenamento em cache.

'after_save' é um método de instância. Você pode configurar uma expectativa para um método de classe, que é por isso que está falhando.

A seguir é a melhor maneira que eu encontrei para definir essa expectativa:

it "should clear the cache" do
  @foo = Foo.new(@create_params)
  Foo.should_receive(:new).with(@create_params).and_return(@foo)

  foo_sweeper = mock('FooSweeper')
  foo_sweeper.stub!(:update)
  foo_sweeper.should_receive(:update).with(:after_save, @foo)

  Foo.instance_variable_set(:@observer_peers, [foo_sweeper])      

  post :create, @create_params
end

O problema é que os observadores do Foo (varredores são uma subclasse de observadores) são definidos quando o Rails botas para cima, por isso temos de inserir o nosso simulada varredor diretamente para o modelo com 'instance_variable_set'.

Outras dicas

Varredores são Singletons e são instanciado no início do teste rspec. Como tal, você pode obtê-lo via MySweeperClass.instance (). Isso funcionou para mim (Rails 3.2):

require 'spec_helper'
describe WidgetSweeper do
  it 'should work on create' do
    user1 = FactoryGirl.create(:user)

    sweeper = WidgetSweeper.instance
    sweeper.should_receive :after_save
    user1.widgets.create thingie: Faker::Lorem.words.join("")
  end
end

Assumindo que você tem:

  • uma classe FooSweeper
  • uma classe Foo com um atributo bar

foo_sweeper_spec.rb:

require 'spec_helper'
describe FooSweeper do
  describe "expiring the foo cache" do
    let(:foo) { FactoryGirl.create(:foo) }
    let(:sweeper) { FooSweeper.instance }
    it "is expired when a foo is updated" do
      sweeper.should_receive(:after_update)
      foo.update_attribute(:bar, "Test")
    end
  end
end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top