Problem
I’ve got an interface which declares
Task DoSomethingAsync();
For my experiments, I’m using MoqFramework:
[TestMethod()]
public async Task MyAsyncTest()
{
Mock<ISomeInterface> mock = new Mock<ISomeInterface>();
mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> });
...
}
Then I run the code that calls await DoSomethingAsync in my test (). And that line is where the test fails. What am I doing incorrectly?
Asked by Waldemar
Solution #1
There’s no reason to use because your method doesn’t contain any callbacks. CallBack(). Using the method, you can simply return a Task with the necessary values. Returns() and Task are two functions that can be used together. For example, consider the following:
MyType someValue=...;
mock.Setup(arg=>arg.DoSomethingAsync())
.Returns(Task.FromResult(someValue));
Update 2014-06-22
To help with this, Moq 4.2 provides two new extension methods.
mock.Setup(arg=>arg.DoSomethingAsync())
.ReturnsAsync(someValue);
mock.Setup(arg=>arg.DoSomethingAsync())
.ThrowsAsync(new InvalidOperationException());
Update 2016-05-05
ReturnsAsync is only available for methods that return a TaskT>, as Seth Flowers points out in the other answer. Only a Task is returned by methods that return only a Task.
.Returns(Task.FromResult(default(object)))
can be used.
In.NET 4.6, as indicated in this response, this is simplified to.Returns(Task.CompletedTask);, for example:
mock.Setup(arg=>arg.DoSomethingAsync())
.Returns(Task.CompletedTask);
Answered by Panagiotis Kanavos
Solution #2
Similar Issue
I had a user interface that looked somewhat like this:
Task DoSomething(int arg);
Symptoms
When my service under test awaited the call to DoSomething, my unit test failed.
Fix
You are unable to call, contrary to popular belief. In this case, you should use ReturnsAsync() on the Setup() of this method because it returns a non-generic Task rather than TaskT>.
You can, however, continue to utilize. On the setup, returns(Task.FromResult(default(object)) allowing the test to pass.
Answered by Seth Flowers
Solution #3
All you have to do now is add. After the Callback, returns(Task.FromResult(0)).
Example:
mock.Setup(arg => arg.DoSomethingAsync())
.Callback(() => { <my code here> })
.Returns(Task.FromResult(0));
Answered by Diego Torres
Solution #4
You can now use Talentsoft as well. https://github.com/TalentSoft/Moq.SetupAsync/wiki/Moq.SetupAsync/wiki/Moq.SetupAsync/wiki/Moq.SetupAsync/wiki/Moq.SetupA
Which of the following, based on the responses collected here and ideas given to Moq but not yet implemented: https://github.com/moq/moq4/issues/384 makes setting up async methods a breeze.
Following are a few examples from earlier SetupAsync responses:
mock.SetupAsync(arg=>arg.DoSomethingAsync());
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => { <my code here> });
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());
Answered by user9812476
Post is based on https://stackoverflow.com/questions/21253523/how-can-i-tell-moq-to-return-a-task