Quelques fois lorsque j'écris des tests d'unité, j'ai besoin d'instancier une classe sans la méthode code> initialiser code> invoquée. Par exemple, lorsque le constructeur instanciait d'autres classes que je remplacerai par des talons de toute façon. Par exemple: dans un test, je remplacerai probablement les deux @Client code> et
@cache code> avec des talons, donc je préférerais que constructeur n'a jamais été invoqué. Y a-t-il une magie noire qui peut m'aider avec ça? P> p>
3 Réponses :
Vous ne devez pas modifier le comportement de la classe testée afin de le tester unitaire. Si votre classe aura plus d'actions dans le constructeur, vous devrez l'imiter à chaque fois. Votre test deviendra fastidieux à entretenir. Remplacez les objets (ou même les classes) avec des doubles.
Vous pourriez peut-être fournir des objets déjà créés comme des arguments au constructeur? Cela vous permettrait d'utiliser des doubles sans encombrement Si vous utilisez RSPEC, vous pouvez: P> nouvelle méthode code> sur les classes. P>
GoogleAnalyticsClient.stub(new: double)
SuperAdvancedCacheSystem.stub(new: double)
Qu'en est-il de la sous-classement De cette façon, vous pouvez même appeler l'initialiseur Exemple d'une spécification minière à l'aide de cette méthode: p> Someclassthatiwilltest code> et écrasement
initialiser code> dans la sous-classe? Aucune magie noire impliquée;)
Super code> (pour tester son code, si c'est plus que vous nous avez montré), puis modifier
@Client Code> et
@cache code> ultérieurement. p>
describe MyTestClass do
subject {
Class.new(MyTestClass) {
def initialize; end
}
}
it "must do something" do
subject.new.do_something.must_equal something
# ...
end
end
Merci d'avoir répondu. J'ai écrit ma propre réponse avec un échantillon de code après avoir lu votre commentaire, je suis donc supprimé ma réponse et j'ai ajouté l'échantillon de code à votre réponse. J'espère que c'est cool.
Vous ne testez plus la classe qui a été supposée d'être testée, mais une sous-classe de celle-ci pourrait changer le comportement et vous ne voulez pas modifier le comportement de ce que vous testez (que cette question propose réellement que je connaisse)
@Runefs: Vous devez à peu près à modifier le comportement par défaut d'une manière ou d'une autre lorsque vous testez des classes qui envoient des demandes aux services externes.
@Codémonkey Si vous injectez vos dépendances, vous n'avez pas besoin de changer le comportement de la classe sous test
@Runefs: Il est essentiel de changer tant de code de production uniquement pour les tests de l'unité ... Je n'ai jamais besoin d'injection de dépendance, sauf dans le cas des tests de l'unité.
@Codemonkey je suppose que c'est là que nos oppinions diffèrent. Cela me semble faux de ne pas tester le code actuel en production, mais pour tester une dérivée de ceux-ci à la place
Bien sûr de pouvoir. Vous pouvez simplement appeler Classe # Nouveau CODE> n'est rien de plus qu'une méthode de commodité qui vous permet d'attribuer manuellement un objet manuellement. Sa mise en œuvre semble grossièrement celle-ci:
class # allouer manuellement code> et ne pas appeler
initialiser p > p>
Ne devrait-il pas être def self.new code>? Merci pour l'information.
Non, Nouveau code> est une méthode d'instance de classe
classe code>. Il y a aussi i> a i> a
classe :: Nouveau code> Singleton, mais qui crée de nouvelles classes, c'est-à-dire des instances de
classe code>.
Classe # Nouveau CODE> Crée des instances des instances de
Classe Code>, I.E. Instances de classes.
Qu'en est-il de la sous-classement
someclassthatiwilltest code> et écrasement
initialiser code> dans la sous-classe? Aucune magie noire impliquée;)
@Tessi: C'est une très bonne idée! Et cela a fonctionné brillamment.
@Codemonkey non, je le reprendis partiellement - s'il va les gérer en interne de l'instanciation à la destruction (sans modification externe), ils n'ont peut-être pas besoin d'être injectés. Veuillez lire sur programmeurs.stackexchange.com/questions/130711/...
@Michaelberkowski: alors nous sommes d'accord
@Codemonkey heureux je pourrais aider. J'écrirai cela comme une réponse (comme c'était vraiment une réponse réellement)