Eu tenho uma interface que declara
Task DoSomethingAsync();
Estou usando o MoqFramework para meus testes:
[TestMethod()]
public async Task MyAsyncTest()
{
Mock<ISomeInterface> mock = new Mock<ISomeInterface>();
mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> });
...
}
Então, no meu teste, eu executo o código que chama await DoSomethingAsync()
. E o teste simplesmente falha nessa linha. O que estou fazendo de errado?
c#
unit-testing
task-parallel-library
moq
Waldemar
fonte
fonte
Respostas:
Seu método não possui retornos de chamada, portanto não há motivo para usá-lo
.CallBack()
. Você pode simplesmente retornar uma tarefa com os valores desejados usando.Returns()
e Task.FromResult , por exemplo:Atualização 22/06/2014
O Moq 4.2 possui dois novos métodos de extensão para ajudar nisso.
Atualização 2016-05-05
Como Seth Flowers menciona na outra resposta ,
ReturnsAsync
só está disponível para métodos que retornam aTask<T>
. Para métodos que retornam apenas uma tarefa,pode ser usado.
Conforme mostrado nesta resposta , no .NET 4.6, isso é simplificado para
.Returns(Task.CompletedTask);
, por exemplo:fonte
.Returns(Task.FromResult(default(object))
funciona bem quando o tipo de retorno é nulo..Returns(Task.FromResult(null as MyType))
funciona bem quando o tipo de retorno esperado é nulo.default(object)
não é mais necessário.null as MyType
é o mesmodefault(MyType)
desde queMyType
seja um tipo de referência.Problema semelhante
Eu tenho uma interface que se parecia com:
Sintomas
Meu teste de unidade falhou quando meu serviço testou
awaited
a chamada paraDoSomething
.Consertar
Ao contrário da resposta aceita, você é incapaz de chamar
.ReturnsAsync()
em suaSetup()
deste método neste cenário, porque o método retorna o não-genéricoTask
, em vez deTask<T>
.No entanto, você ainda pode usar
.Returns(Task.FromResult(default(object)))
a configuração, permitindo que o teste seja aprovado.fonte
Você só precisa adicionar
.Returns(Task.FromResult(0));
após o retorno de chamada.Exemplo:
fonte
Agora você também pode usar o pacote Talentsoft.Moq.SetupAsync https://github.com/TalentSoft/Moq.SetupAsync
Que, com base nas respostas encontradas aqui e nas idéias propostas ao Moq, mas ainda não implementadas aqui: https://github.com/moq/moq4/issues/384 , simplifica bastante a configuração dos métodos assíncronos
Poucos exemplos encontrados em respostas anteriores feitas com a extensão SetupAsync:
fonte