Question

Je veux vous assurer que mon balai est appelé selon le cas, donc j'ai essayé d'ajouter quelque chose comme ceci:

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

Mais je viens d'obtenir:

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

J'ai essayé d'allumer la mise en cache dans la configuration de test, mais qui ne fait aucune différence.

Était-ce utile?

La solution

Comme vous l'avez déjà mentionné la mise en cache doit être activé dans l'environnement pour que cela fonctionne. Si elle est désactivée alors mon exemple ci-dessous échouera. Il est probablement une bonne idée de permettre temporairement ce lors de l'exécution de vos spécifications de mise en cache.

'after_save' est une méthode d'instance. Vous configurer une attente pour une méthode de classe, ce qui explique pourquoi il est défaillant.

Ce qui suit est la meilleure façon que je l'ai trouvé pour régler cette attente:

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

Le problème est que les observateurs de Foo (les balayeurs sont une sous-classe d'observateurs) sont fixés lors du démarrage Rails, donc nous devons insérer notre maquette de balayeuse directement dans le modèle avec « instance_variable_set ».

Autres conseils

Sweepers sont singletons et sont instanciés au début du test rspec. A ce titre, vous pouvez y accéder via MySweeperClass.instance (). Cela a fonctionné pour moi (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

En supposant que vous avez:

  • une classe FooSweeper
  • une classe Foo avec un attribut 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top