可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've got an interface which declares
Task DoSomethingAsync();
I'm using MoqFramework for my tests:
[TestMethod()] public async Task MyAsyncTest() { Mock mock = new Mock(); mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { }); ... }
Then in my test I execute the code which invokes await DoSomethingAsync()
. And the test just fails on that line. What am I doing wrong?
回答1:
Your method doesn't have any callbacks so there is no reason to use .CallBack()
. You can simply return a Task with the desired values using .Returns()
and Task.FromResult, e.g.:
MyType someValue=...; mock.Setup(arg=>arg.DoSomethingAsync()) .Returns(Task.FromResult(someValue));
Update 2014-06-22
Moq 4.2 has two new extension methods to assist with this.
mock.Setup(arg=>arg.DoSomethingAsync()) .ReturnsAsync(someValue); mock.Setup(arg=>arg.DoSomethingAsync()) .ThrowsAsync(new InvalidOperationException());
Update 2016-05-05
As Seth Flowers mentions in the other answer, ReturnsAsync
is only available for methods that return a Task
. For methods that return only a Task,
.Returns(Task.FromResult(default(object)))
can be used.
As shown in this answer, in .NET 4.6 this is simplified to .Returns(Task.CompletedTask);
, e.g.:
mock.Setup(arg=>arg.DoSomethingAsync()) .Returns(Task.CompletedTask);
回答2:
Similar Issue
I have an interface that looked roughly like:
Task DoSomething(int arg);
Symptoms
My unit test failed when my service under test awaited
the call to DoSomething
.
Fix
Unlike the accepted answer, you are unable to call .ReturnsAsync()
on your Setup()
of this method in this scenario, because the method returns the non-generic Task
, rather than Task
.
However, you are still able to use .Returns(Task.FromResult(default(object)))
on the setup, allowing the test to pass.
回答3:
You only need to add .Returns(Task.FromResult(0));
after the Callback.
Example:
mock.Setup(arg => arg.DoSomethingAsync()) .Callback(() => { }) .Returns(Task.FromResult(0));