Peut RSpec écrasé de retour de méthode de valeurs différentes dans la séquence?
J'ai un modèle de la Famille avec une méthode location
qui fusionne les location
les résultats d'autres objets, les Membres. (Les membres sont associés avec les familles, mais ce n'est pas important ici).
Par exemple, étant donné
- member_1 a
location
== 'San Diego (voyages, renvoie 15 Mai)' - member_2 a
location
= = "San Diego"
De la famille.emplacement peut-retour 'de San Diego (member_1 voyage, renvoie 15 Mai)" Les détails ne sont pas importants.
Pour simplifier le test de la Famille.l'emplacement, je veux stub Membre.emplacement. Cependant, j'ai besoin de retourner deux (spécifié) valeurs comme dans l'exemple ci-dessus. Idéalement, celle-ci serait basée sur un attribut de member
, mais simplement de retourner des valeurs différentes dans une séquence serait OK. Est-il un moyen de le faire dans RSpec?
Il est possible de remplacer le Membre.la méthode de localisation à l'intérieur de chaque exemple de test, tels que
it "when residence is the same" do
class Member
def location
return {:residence=>'Home', :work=>'his_work'} if self.male?
return {:residence=>'Home', :work=>'her_work'}
end
end
@family.location[:residence].should == 'Home'
end
mais je doute que c'est une bonne pratique. En tout cas, quand RSpec est en cours d'exécution d'une série d'exemples, il ne restitue pas la classe d'origine, si ce genre de remplacer les "poisons" les exemples suivants.
Alors, est-il un moyen d'avoir un écrasé de retour des méthodes différentes, des valeurs spécifiées sur chaque appel?
Vous devez vous connecter pour publier un commentaire.
Vous pouvez stub une méthode pour renvoyer des valeurs différentes à chaque fois qu'il est appelé;
Donc la première fois que vous appelez
@family.location
il sera de retour 'first', la deuxième fois, il sera de retour "deuxième", et toutes les fois que vous l'appelez, ce sera le retour de "l'autre".my_big_array
, vous pourriez faireallow(@family).to receive(:location).and_return(*my_big_array)
. Espérons que cette aide.RSpec 3 syntaxe:
Si pour une raison quelconque vous souhaitez utiliser l'ancienne syntaxe, vous pouvez toujours:
La solution retenue ne doit être utilisé que si vous avez un nombre spécifique d'appels et de la nécessité d'une séquence spécifique de données. Mais que faire si vous ne savez pas le nombre d'appels qui seront faites, ou ne se soucient pas de l'ordre des données seulement que c'est quelque chose de différent à chaque fois? Que l'OP a dit:
Le problème avec
and_return
est que la valeur de retour est memoized. Ce qui signifie que même si vous voulez revenir à quelque chose de dynamique, vous obtiendrez toujours la même.E. g.
Ou un exemple concret serait l'aide d'usines et d'obtenir le même Id:
Dans ces cas, vous pouvez stub le corps de la méthode pour avoir le code exécuté à chaque fois:
Remarque que vous n'avez pas accès à l'objet de Membre via
self
dans ce contexte, mais peut utiliser les variables dans le cadre test.E. g.
J'ai essayé la solution de décrire ci-dessus, mais il ne fonctionne pas pour moi. J'ai résolu le problème en les écrasant avec un substitut de la mise en œuvre.
Quelque chose comme: