Estou começando a usar o Moq e lutando um pouco. Estou tentando verificar se messageServiceClient está recebendo o parâmetro correto, que é um XmlElement, mas não consigo encontrar nenhuma maneira de fazê-lo funcionar. Funciona apenas quando não verifico um valor específico.
Resposta parcial: Encontrei uma maneira de testar se o xml enviado ao proxy está correto, mas ainda não acho que seja a maneira correta de fazê-lo.
A propósito, como eu poderia extrair a expressão da chamada Verificar?
— Luis Mirabal
Se a lógica de verificação não for trivial, será complicado escrever um método lambda grande (como mostra o exemplo). Você pode colocar todas as instruções de teste em um método separado, mas eu não gosto de fazer isso porque isso interrompe o fluxo de leitura do código de teste.
Outra opção é usar um retorno de chamada na instalação para armazenar o valor que foi passado para o método simulado e, em seguida, escrever Assertmétodos padrão para validá-lo. Por exemplo:
— Rich Tebb
Um grande benefício dessa abordagem é que ela fornecerá falhas de teste específicas sobre como o objeto está incorreto (conforme você está testando cada um individualmente).
— Rob Church
Eu pensei que era o único que fez isso, feliz por ver que é uma abordagem razoável!
Acho que usando It.Is <MyObject> (validador) conforme Mayo é melhor, pois evita a maneira um pouco estranha de salvar o valor do parâmetro como parte do lambda
esse thread é seguro, por exemplo, ao executar testes em paralelo?
— Anton Tolken 22/07/19
@AntonTolken Eu não tentei, mas no meu exemplo, o objeto que é atualizado é uma variável local (saveObject), portanto deve ser seguro para threads.
— Rich Tebb 23/07/19
Venho verificando as chamadas da mesma maneira - acredito que é a maneira correta de fazer isso.
Se sua expressão lambda se tornar pesada, você poderá criar uma função que assume MyObjectcomo entrada e saída true/ false...
Além disso, esteja ciente de um bug no Mock, no qual a mensagem de erro informa que o método foi chamado várias vezes quando não foi chamado. Eles podem ter corrigido isso agora - mas se você vir essa mensagem, poderá verificar se o método foi realmente chamado.
EDIT: Aqui está um exemplo de chamada verificar várias vezes para os cenários em que você deseja verificar se você chama uma função para cada objeto em uma lista (por exemplo).
A mesma abordagem para a instalação ...
Portanto, toda vez que o GetStuff for chamado para esse itemId, ele retornará itens específicos para esse item. Como alternativa, você pode usar uma função que tome itemId como entrada e retorne itens.
Um outro método que eu vi em um blog algum tempo atrás (Phil Haack talvez?) Tinha a configuração retornando de algum tipo de objeto de desenfileiramento - cada vez que a função era chamada, ele puxava um item de uma fila.
Obrigado, faz sentido para mim. O que ainda não consigo entender é quando especificar detalhes em Configuração ou Verificar. É bem confuso. No momento, estou apenas permitindo qualquer coisa na instalação e especificando os valores na verificação.
Como você acha que posso verificar as mensagens quando há várias chamadas? O cliente recebe mensagens e pode criar várias mensagens queueable, que terminarão em várias chamadas e, em cada uma dessas chamadas, tenho que verificar mensagens diferentes. Ainda estou lutando com testes de unidade em geral, ainda não estou muito familiarizado com isso.
Eu não acho que exista uma bala mágica de prata em termos de como você deve fazer isso. É preciso prática e você começa a melhorar. Para mim, só especifico parâmetros quando tenho algo para compará-los e quando ainda não estou testando esse parâmetro em outro teste. Quanto a várias chamadas, existem várias abordagens. Para configurar e verificar uma função chamada várias vezes, costumo chamar setup ou verificar (Times.Once ()) para cada chamada que espero - geralmente com um loop for. Você pode usar os parâmetros específicos para isolar cada chamada.
Adicionei alguns exemplos para várias chamadas - veja a resposta acima.
"Além disso, esteja ciente de um bug no Mock, no qual a mensagem de erro afirma que o método foi chamado várias vezes quando não foi chamado. Eles podem ter corrigido o problema agora - mas se você vir essa mensagem, considere verificar se o método foi realmente chamado ". - Um bug como esse invalida completamente uma biblioteca de zombaria IMHO. Como é irônico que eles não têm código de teste adequado para ele :-)
Uma maneira mais simples seria fazer:
— dmitry.sergeyev
Não consigo fazer isso funcionar, estou tentando verificar se meu método foi chamado com o Code.WRCC como parâmetro. Mas meu teste passa sempre, mesmo que o parâmetro passado é WRDD .. m.Setup(x => x.CreateSR(Code.WRDD)).ReturnsAsync(0); await ClassUnderTest.CompleteCC(accountKey, It.IsAny<int>(), mockRequest); m.Verify(x => x.CreateSR(It.Is<Code>(p => p == Code.WRCC)), Times.Once());
Eu acredito que o problema no fato de que Moq irá verificar a igualdade. E, como XmlElement não substitui Equals, sua implementação verificará a igualdade de referência.
Você não pode usar um objeto personalizado para substituir os iguais?
Sim, acabei fazendo isso. Percebi que o problema estava verificando o Xml. Na segunda parte da pergunta I adicionou-se uma possível resposta deserialising o XML para um objecto
Tinha um desses também, mas o parâmetro da ação era uma interface sem propriedades públicas. Acabou usando It.Is () com um método separado e, dentro desse método, foi necessário zombar da interface