Sto provando a testare una classe di servizio, che utilizza internamente un oggetto di connessione AMQP Spring. Questo oggetto di connessione è iniettato da Spring. Tuttavia, non voglio che il mio test unitario comunichi effettivamente con il broker AMQP, quindi sto usando Mockito per iniettare una simulazione dell'oggetto di connessione.In che modo Mockito può acquisire gli strumenti passati ai metodi di un oggetto fittizio iniettato?
/**
* 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.
}
}
I commenti in questo esempio di codice si spera siano disposti chiaramente. Quando Mockito inietta una dipendenza fittizia in una classe reale, e i test unitari sulla classe reale provocano le chiamate alla simulazione, come puoi recuperare in seguito gli argomenti esatti che sono stati trasmessi al mock iniettato?
Grazie per la punta su 'doAnswer()' 'vs. DoNothing()', mi hanno ripulito il codice di esempio sopra di conseguenza. Tuttavia, non sono sicuro se mi manchi qualcosa, o se la tua risposta è ancora un livello rimosso dal mio problema. Quando comincio chiamando 'verify()' sul mio oggetto mock PRIMA che abbia chiamato la vera classe che usa internamente il mock, allora ottengo il messaggio di eccezione, "In realtà, non c'erano interazioni nulle con questo mock". L'esecuzione fallisce sulla riga 'verify()' e non arriva mai nemmeno al codice reale che sto provando a testare. –
Nel tuo esempio, stai cercando di passare un argomento al tuo oggetto mock direttamente dal test dell'unità? Non sto ... Sto cercando di catturare un argomento che è passato da uno strato intermedio tra il test unitario e l'oggetto simulato. La finta viene iniettata in questo intermediario. –
Ahh! Il problema che non è chiaro dal tuo snippet è che la chiamata 'verify()' sul mock, così come la chiamata 'getValue()' sul captor, entrambi vengono DOPO l'invocazione del metodo sull'oggetto reale effettivamente sotto test. Ho erroneamente chiamato 'verify()' prima dell'invocazione del metodo dell'oggetto reale. –