Comment peut-Mockito capture d'arguments passés à l'injection d'une maquette de l'objet de méthodes?
Je suis en train de tester un service de classe, en interne qui rend l'utilisation d'un Ressort AMQP objet de connexion. Cet objet de connexion est injecté par le Printemps. Cependant, je ne veux pas que mon test de l'unité de réellement communiquer avec le courtier AMQP, donc je suis en utilisant Mockito injecter un simulacre de l'objet de connexion.
/**
* The real service class being tested. Has an injected dependency.
*/
public class UserService {
@Autowired
private AmqpTemplate amqpTemplate;
public final String doSomething(final String inputString) {
final String requestId = UUID.randomUUID().toString();
final Message message = ...;
amqpTemplate.send(requestId, message);
return requestId;
}
}
/**
* Unit test
*/
public class UserServiceTest {
/** This is the class whose real code I want to test */
@InjectMocks
private UserService userService;
/** This is a dependency of the real class, that I wish to override with a mock */
@Mock
private AmqpTemplate amqpTemplateMock;
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testDoSomething() {
doNothing().when(amqpTemplateMock).send(anyString(), any(Message.class));
//Call the real service class method, which internally will make
//use of the mock (I've verified that this works right).
userService.doSomething(...);
//Okay, now I need to verify that UUID string returned by
//"userService.doSomething(...) matches the argument that method
//internally passed to "amqpTemplateMock.send(...)". Up here
//at the unit test level, how can I capture the arguments passed
//to that inject mock for comparison?
//
//Since the value being compared is a UUID string created
//internally within "userService", I cannot just verify against
//a fixed expected value. The UUID will by definition always be
//unique.
}
}
Les commentaires dans cet exemple de code espérons-le, poser la question clairement. Lorsque Mockito injecte un simulacre de dépendance dans une vraie classe, et des tests unitaires sur la véritable cause de la classe pour faire des appels à la maquette, comment pouvez-vous récupérer plus tard exactement les arguments qui ont été transmis à l'injection de fantaisie?
Vous devez vous connecter pour publier un commentaire.
Utiliser un, ou plusieurs,
ArgumentCaptor
s.Il est difficile de savoir ce que vos types sont ici, mais de toute façon. Supposons que vous avez une maquette qui a une méthode
doSomething()
prendre unFoo
comme un argument, puis vous faites cela:Aussi, il ressemble à la méthode void et vous n'avez pas envie de faire quoi que ce soit. Il suffit d'écrire ceci:
doAnswer()
vsdoNothing()
, j'ai nettoyé le code ci-dessus de l'échantillon en conséquence. Cependant, je ne suis pas sûr si je suis absent quelque chose, ou si votre réponse est encore un niveau retiré de mon problème. Quand je commence à en appelantverify()
sur ma maquette de l'objet AVANT que j'ai appelé le réel de la classe qui utilise la maquette à l'interne, puis je reçois le message d'exception, "en Fait, il y avait zéro interactions avec ce simulacre". L'exécution échoue sur leverify()
ligne... et n'a même jamais fait pour le code réel que je suis en train de tester.verify()
appel sur la maquette, ainsi que lagetValue()
appel sur le capteur, les deux viennent APRÈS l'invocation de la méthode sur l'objet réel fait l'objet de test. J'ai été à tort d'appelerverify()
préalable à l'objet réel d'invocation de méthode.Vous pouvez brancher
doAnswer()
à la stub de lasend()
méthode suramqpTemplateMock
puis capturer l'invocation d'arguments deAmqpTemplate.send()
.La première ligne de votre
testDoSomething()
être cemettre tous ensemble, le test devient
Cela donne de sortie
J'ai trouvé ceci par la lecture de ce post,
Comment faire de la maquette à des méthodes void avec mockito