首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >xUnit和Moq不支持async - await关键字

xUnit和Moq不支持async - await关键字
EN

Stack Overflow用户
提问于 2012-06-28 00:06:35
回答 2查看 9.1K关注 0票数 21

我正在尝试探索如何将async和await关键字应用于我的xUnit测试。我正在使用xUnit 1.9和Async CTP1.3。这是我的测试用例

我有一个接口,它指定一个异步方法调用

代码语言:javascript
复制
public interface IDoStuffAsync
{
    Task AnAsyncMethod(string value);
}

我有一个使用接口并调用async方法的类

代码语言:javascript
复制
public class UseAnAsyncThing
{
    private readonly IDoStuffAsync _doStuffAsync;

    public UseAnAsyncThing(IDoStuffAsync doStuffAsync)
    {
        _doStuffAsync = doStuffAsync;
    }

    public async Task DoThatAsyncOperation(string theValue)
    {
        await _doStuffAsync.AnAsyncMethod(theValue);
    }
}

在我的测试中,我希望检查方法DoThatAsyncOperation是否使用正确的值调用该方法,因此我模拟接口并使用Moq来验证调用

代码语言:javascript
复制
    [Fact]
    public async void The_test_will_pass_even_though_it_should_fail()
    {
        var mock = new Mock<IDoStuffAsync>();
        var sut = new UseAnAsyncThing(mock.Object);

        mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>()));

        await sut.DoThatAsyncOperation("test");

        // This won't throw a Moq.MockExcpetion so the test appears to pass
        // However it does not run
        mock.Verify(x => x.AnAsyncMethod("fail"));
    }

此测试使用asyncawait关键字。当它运行时,它会错误地传递给Moq,因为它应该断言验证失败。调用sut.DoThatAsyncOperation("test");之后的任何代码都不会运行

代码语言:javascript
复制
    [Fact]
    public void This_will_work_and_assert_the_reslt()
    {
        var mock = new Mock<IDoStuffAsync>();
        var sut = new UseAnAsyncThing(mock.Object);

        mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>()));

        sut.DoThatAsyncOperation("test").ContinueWith(y => { });

        // This won't throw a Moq.MockExcpetion so the test appears to pass
        // However it does not run
        mock.Verify(x => x.AnAsyncMethod("fail"));
    }

这个测试没有设置await和async关键字,并且通过得很好。

这是xUnit和Moq的预期行为吗?

更新

感谢Stephen的评论,我成功地修复了第一个测试,做了两个更改。测试现在返回一个Task而不是void,而Mock也返回一个Task。

代码语言:javascript
复制
    [Fact]
    public async Task The_test_will_pass_even_though_it_should_fail()
    {
        var mock = new Mock<IDoStuffAsync>();
        var sut = new UseAnAsyncThing(mock.Object);

        mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>())).ReturnAsync(true);

        await sut.DoThatAsyncOperation("test");

        // This now fails as it should
        mock.Verify(x => x.AnAsyncMethod("fail"));
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-28 02:00:00

将您的单元测试方法更改为返回Task而不是void,它应该可以工作。支持is being considered for a future releaseasync void单元测试。

我在我的博客上详细描述了why async unit tests don't work by default。(我的博客示例使用MSTest,但在所有其他测试运行器中都存在相同的问题,包括xUnit 1.9之前的版本)。

票数 15
EN

Stack Overflow用户

发布于 2014-01-23 08:37:04

我试图使用你的“更新”中的代码,但它在我模仿的异步方法处停止了。

代码语言:javascript
复制
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(default(T));


    mock.Setup(x => x.AnAsyncMethod(It.IsAny<T>())).Returns(tcs.Task);

因此,为了解决这个问题,我必须更改“Return”方法:

代码语言:javascript
复制
    mock.Setup(x => x.AnAsyncMethod(It.IsAny<T>())).Returns(()=> { return tcs.Task; } );
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11230567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档