81 votes

Comment dire "n'importe quelle instance" "devrait_receive" autant de fois qu'il est dans RSpec

J'ai un contrôleur d'importation dans les rails qui importe plusieurs fichiers CSV avec plusieurs enregistrements dans ma base de données. Je voudrais tester dans RSpec si les enregistrements sont réellement enregistrés en utilisant RSpec:

 <Model>.any_instance.should_receive(:save).at_least(:once)
 

Cependant, je reçois l'erreur en disant:

 The message 'save' was received by <model instance> but has already been received by <another model instance>
 

Un exemple artificiel du contrôleur:

 rows = CSV.parse(uploaded_file.tempfile, col_sep: "|")

  ActiveRecord::Base.transaction do
    rows.each do |row| 
    mutation = Mutation.new
    row.each_with_index do |value, index| 
      Mutation.send("#{attribute_order[index]}=", value)
    end
  mutation.save          
end
 

Est-il possible de tester cela avec RSpec ou existe-t-il une solution de contournement?

55voto

Rob Points 2006

Voici une meilleure réponse qui évite d'avoir à remplacer la: nouvelle méthode:

 save_count = 0
<Model>.any_instance.stub(:save) do |arg|
    # The evaluation context is the rspec group instance,
    # arg are the arguments to the function. I can't see a
    # way to get the actual <Model> instance :(
    save_count+=1
end
.... run the test here ...
save_count.should > 0
 

Il semble que la méthode stub puisse être attachée à n'importe quelle instance sans la contrainte, et que le bloc do peut faire un compte que vous pouvez vérifier pour affirmer qu'il a été appelé le nombre de fois correct.

46voto

muirbot Points 942

Voici une nouvelle syntaxe pour cela:

 expect_any_instance_of(Model).to receive(:save).at_least(:once)
 

15voto

Harm de Wit Points 721

J'ai finalement réussi à faire un test qui fonctionne pour moi:

   mutation = FactoryGirl.build(:mutation)
  Mutation.stub(:new).and_return(mutation)
  mutation.should_receive(:save).at_least(:once)
 

La méthode stub renvoie une seule instance qui reçoit la méthode de sauvegarde plusieurs fois. Comme il s’agit d’une instance unique, je peux abandonner la méthode any_instance et utiliser la méthode at_least normalement.

11voto

michelpm Points 728

Stub comme ça

 User.stub(:save) # Could be any class method in any class
User.any_instance.stub(:save) { |*args| User.save(*args) }
 

Alors attendez-vous comme ça:

 # User.any_instance.should_receive(:save).at_least(:once)
User.should_receive(:save).at_least(:once)
 

Ceci est une simplification de cet élément essentiel , à utiliser any_instance , car il n'est pas nécessaire d'utiliser un proxy pour la méthode d'origine. Reportez-vous à cette substance pour d'autres utilisations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X