Imagine essa aula
public class Foo {
private Handler _h;
public Foo(Handler h)
{
_h = h;
}
public void Bar(int i)
{
_h.AsyncHandle(CalcOn(i));
}
private SomeResponse CalcOn(int i)
{
...;
}
}
Mo (q) cking Handler em um teste de Foo, como eu seria capaz de verificar o que Bar()
passou _h.AsyncHandle
?
Respostas:
Você pode usar o método Mock.Callback:
Se você quiser apenas verificar algo simples no argumento passado, também poderá fazê-lo diretamente:
fonte
Callback<>()
método Moq genérico . Por exemplo, se seu método tivesse a definiçãoHandler.AnsyncHandle(string, SomeResponse)
, você precisaria/* ... */.Callback<string, SomeResponse>(r => result = r);
. Eu não encontrei isso explicitamente declarado em muitos lugares, então achei que o adicionaria aqui./* ... */.Callback<string, SomeResponse>((s1, s2) => { str1 = s1; result = s2});
.Callback((string s1, SomeResponse s2) => /* stuff */ )
Capture.In
auxiliar interno?A resposta de Gamlor funcionou para mim, mas pensei em expandir o comentário de John Carpenter porque estava procurando uma solução que envolvesse mais de um parâmetro. Imaginei que outras pessoas que tropeçam nessa página podem estar em uma situação semelhante. Encontrei essas informações na documentação do Moq .
Usarei o exemplo de Gamlor, mas vamos fingir que o método AsyncHandle usa dois argumentos: a
string
e umSomeResponse
objeto.Basicamente, você só precisa adicionar outro
It.IsAny<>()
com o tipo apropriado, adicionar outro tipo aoCallback
método e alterar a expressão lambda conforme apropriado.fonte
O método de retorno de chamada certamente funcionará, mas se você estiver fazendo isso em um método com muitos parâmetros, pode ser um pouco detalhado. Aqui está algo que eu usei para remover parte do clichê.
Aqui está a fonte do ArgumentCaptor:
fonte
A resposta de Gamlor funciona, mas outra maneira de fazê-lo (e uma que considero mais expressiva no teste) é ...
A verificação é muito poderosa e vale a pena se acostumar.
fonte
A alternativa é também usar o
Capture.In
recurso domoq
. É omoq
recurso OOTB que permite a captura de argumentos na coleção.fonte
Callback
IMO. Como você usa o Capture diretamente na lista de parâmetros, é muito menos suscetível a problemas ao refatorar a lista de parâmetros de um método e, portanto, torna os testes menos frágeis. Com o retorno de chamada, você deve manter os parâmetros passados na instalação em sincronia com os parâmetros de tipo usados para o retorno de chamada, e isso definitivamente me causou problemas no passado.Você poderia usar o
It.Is<TValue>()
matcher.fonte
Isso também funciona:
fonte
Muitas boas respostas aqui! Vá com o conjunto de recursos Moq pronto para uso até precisar fazer afirmações sobre vários parâmetros de classe passados para suas dependências. No entanto, se você acabar nessa situação, o recurso Moq Verify com It.Is não faz um bom trabalho em isolar a falha do teste, e a maneira de capturar retornos / retorno de chamada adiciona linhas de código desnecessárias ao seu teste (e testes longos não são para mim).
Aqui está uma síntese: https://gist.github.com/Jacob-McKay/8b8d41ebb9565f5fca23654fd944ac6b com uma extensão do Moq (4.12) que eu escrevi, que fornece uma maneira mais declarativa de fazer afirmações sobre argumentos passados para zombarias, sem os inconvenientes mencionados acima. Aqui está a aparência da seção Verificar agora:
Eu ficaria feliz se o Moq fornecesse um recurso que realizasse a mesma coisa, sendo tão declarativo e fornecendo o isolamento de falhas que isso faz. Dedos cruzados!
fonte