Acho que no meu caso isso não se aplicaria...
Vou tentar descrever a situação:
Estou testando um serviço, que possui um método chamado update(). Este método carrega uma lista de objetos do banco de dados e, com base nos atributos destes objetos, escreve alguns bytes na porta serial.
Eu criei algumas interfaces para desacoplar a api de comunicação serial, então posso simular qualquer situação sem dificuldades nos testes, a saber:
SerialPortManager, que é como um factory para as portas seriais
SerialPort, que é a porta propriamente dita.
Eu identifiquei uma situação em que ao escrever um byte na porta, o método simplesmente não retorna e o serviço fica parado, então decidi que o serviço vai abrir uma nova thread que por sua vez será responsável por realizar a comunicação, e o service monitora a thread para ver se ela está demorando muito a finalizar: Se isso acontecer, ele marca um flag indicando que a porta não está respondendo, e na próxima chamada a update() ele irá forçar um close() na porta e abri-la novamente, hoje este é o código do teste:
?[code]?
@Timeout(10)
void "Se a porta demorar a responder, na próxima iteração deve ser fechada e reaberta"() {
setup:
def com3_a = Mock(SerialPort) {
1*writeByte(8) >> {
// Para simular uma porta que não responde
def initial = System.currentTimeMillis()
for (;;) {
if (System.currentTimeMillis() - initial > 20*1000)
break
}
}
}
def com3_b = Mock(SerialPort) {
1*writeByte(8)
}
when:
service.update()
service.update()
then:
1*serialPortManager.open("COM3", _) >> com3_a
then:
1*com3_a.close()
then:
1*serialPortManager.open("COM3", _) >> com3_b
}[/code]
O que acontece é que na primeira chamada a update, o método vai dar um serialPortManager.open(...), que por sua vez irá retornar o mock com3_a. Ao chamar o método writeByte, vai entrar naquele loop que demora 20 segundos para terminar.
Acontece que a chamada a writeByte é feita dentro de uma outra thread, e se o service ver que ela está levando mais de 5 segundos para terminar, vai marcar aquele flag que falei e vai seguir sua execução normalmente até retornar.
Quando da segunda chamada a update(), o service vai dar um .close() naquele mock com3_a e irá chamar novamente serialPortManager.open(...), que agora retornará o mock com3_b.
O service abre novamente a thread, chama o método .writeByte neste segundo mock, que retorna normalmente e a execução termina. O teste teria passado, só que eu anotei o método de teste com um timeout de 10 segundos, e a execução está levando em torno de 20 segundos (lembra que 20 segundos é o tempo que eu programei naquele primeiro mock?)
Através dos logs produzidos pelo service, pude constatar que a segunda chamada a serialPortManager.open() só retorna depois que terminam os 20 segundos que começaram a contar quando daquela chamada a writeBytes lá atras, o que me leva a crer que qualquer chamada a um método mockado só vai ocorrer quando qualquer chamada anterior tiver terminado (mesmo sendo em threads diferentes).