2009-02-15 10 views
2

Je veux vous assurer que mon balai est appelé selon le cas, donc j'ai essayé d'ajouter quelque chose comme ceci:Test d'une balayeuse avec RSpec dans Rails

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 reçois juste:

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

I J'ai essayé d'activer la mise en cache dans la configuration de test, mais cela n'a fait aucune différence.

Répondre

3

Comme vous l'avez déjà mentionné, la mise en cache doit être activée dans l'environnement pour que cela fonctionne. Si elle est désactivée, mon exemple ci-dessous échouera. C'est probablement une bonne idée de l'activer temporairement lors de l'exécution pour vos spécifications de mise en cache. 'After_save' est une méthode d'instance. Vous définissez une attente pour une méthode de classe, ce qui explique pourquoi elle échoue.

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 (balayeuses sont une sous-classe d'observateurs) sont fixés lors du démarrage Rails, donc nous avons pour insérer notre sweeper directement dans le modèle avec 'instance_variable_set'.

2

Les balayeuses sont des singletons et sont instanciées au début du test rspec. En tant que tel, 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 
2

En supposant que vous avez:

  • une FooSweeper classe
  • une classe Foo avec un bar attribut

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 
Questions connexes