Prefácio : Eu sou bem versado na magia negra que é o teste assíncrono em Kiwi. Esta dica não é sobre como escrever um teste assíncrono, mas, sim, enganar o Kiwi para que obedeça aos seus stubs, independentemente do tipo de teste que você está escrevendo. Além disso, estou preso na versão 2.0.5 porque a equipe Kiwi fez algumas coisas hilariantes em uma versão de correção que mudou a operação principal dos stubs. Se você tiver uma versão diferente, sua milhagem pode variar.
Avante!
Você pode pensar que fazer algo assim [obj stub:@selector(foo:bar:)]
seria suficiente para stub em Kiwi.
Você está errado.
Não se sinta mal. Não é sua culpa. É culpa do Kiwi.
Vou lhe dizer como fazer as coisas voltarem ao controle.
Imagine que você tem um método semelhante a este:
- (void)flingPoo:(NSString *)message
{
dispatch_async(dispatch_get_main_queue(), ^{
[NSNotificationCenter.defaultCenter postNotification:message];
}
}
Veja como essa notificação está saindo de forma assíncrona? Sim, você vê isso, mas Kiwi não. Vamos escrever um teste para que Kiwi entenda. Seria algo assim.
#define MSG @"Hello, gents"
describe(@"flingPoo:", ^{
__block AYMonkey *monkey;
beforeEach(^{
monkey = [AYMonkey new];
[NSNotificationCenter.defaultCenter stub:@selector(postNotification:)];
});
afterEach(^{
monkey = nil;
});
it(@"should fling the message without locking", ^{
[[NSNotificationCenter.defaultCenter shouldEventually] receive:@selector(postNotification:) withArguments:MSG];
[monkey flingPoo:MSG];
});
});
Você vê? É sutil.
Eu usei em shouldEventually
vez de should
. Usar shouldEventually
gatilhos Kiwi para executar tudo esperando um resultado assíncrono e, assim, evitar a comédia da tragédia que é notificações vazando inesperadamente de suas especificações.
Se ajudar, pense nisso como um ternário pseudocódigo: cmd action = (method.doesSomethingAsync) ? shouldEventually : should;
.
Espero que isso economize pelo menos uma pessoa algumas horas de depuração de bugs e travamentos baseados em notificação em seu pacote Kiwi. Boa sorte!