How can I tell Moq to return a Task?

前端 未结 4 1419
盖世英雄少女心
盖世英雄少女心 2020-11-27 09:56

I\'ve got an interface which declares

Task DoSomethingAsync();

I\'m using MoqFramework for my tests:

[TestMethod()]
public          


        
相关标签:
4条回答
  • 2020-11-27 10:19

    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<T>. 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);
    
    0 讨论(0)
  • 2020-11-27 10:19

    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<T>.

    However, you are still able to use .Returns(Task.FromResult(default(object))) on the setup, allowing the test to pass.

    0 讨论(0)
  • 2020-11-27 10:24

    You only need to add .Returns(Task.FromResult(0)); after the Callback.

    Example:

    mock.Setup(arg => arg.DoSomethingAsync())
        .Callback(() => { <my code here> })
        .Returns(Task.FromResult(0));
    
    0 讨论(0)
  • 2020-11-27 10:29

    Now you can also use Talentsoft.Moq.SetupAsync package https://github.com/TalentSoft/Moq.SetupAsync

    Which on the base on the answers found here and ideas proposed to Moq but still not yet implemented here: https://github.com/moq/moq4/issues/384, greatly simplify setup of async methods

    Few examples found in previous responses done with SetupAsync extension:

    mock.SetupAsync(arg=>arg.DoSomethingAsync());
    mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => { <my code here> });
    mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());
    
    0 讨论(0)
提交回复
热议问题