的xUnit和起订量不支持异步 - 等待关键词 [英] xUnit and Moq do not support async - await keywords

查看:156
本文介绍了的xUnit和起订量不支持异步 - 等待关键词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图探索如何应用异步和等待关键字来我的xUnit测试。我使用的xUnit 1.9和异步CTP 1.3。这里是我的测试用例

我有一个指定了一个异步方法调用

接口

 公共接口IDoStuffAsync
{
    任务AnAsyncMethod(字符串值);
}

我有一个消费的接口,并调用异步方法的类

 公共类UseAnAsyncThing
{
    私人只读IDoStuffAsync _doStuffAsync;    公共UseAnAsyncThing(IDoStuffAsync doStuffAsync)
    {
        _doStuffAsync = doStuffAsync;
    }    公共异步任务DoThatAsyncOperation(字符串theValue)
    {
        等待_doStuffAsync.AnAsyncMethod(theValue);
    }
}

在我的测试中,我想检查方法 DoThatAsyncOperation 呼吁用正确的值的方法,所以我嘲笑界面,可以用最小起订量来确认来电

  [事实]
    公共异步无效The_test_will_pass_even_though_it_should_fail()
    {
        VAR模拟=新模拟< IDoStuffAsync>();
        VAR SUT =新UseAnAsyncThing(mock.Object);        mock.Setup(X => x.AnAsyncMethod(It.IsAny&所述;串GT;()));        等待sut.DoThatAsyncOperation(测试);        //所以测试似乎通过这不会抛出Moq.MockExcpetion
        //但是它不运行
        mock.Verify(X => x.AnAsyncMethod(不及格));
    }

此测试是使用异步等待关键字。当它运行时,它错误地传递为起订量应该断言验证失败。任何code,来电后 sut.DoThatAsyncOperation(测试); 不运行

  [事实]
    公共无效This_will_work_and_assert_the_reslt()
    {
        VAR模拟=新模拟< IDoStuffAsync>();
        VAR SUT =新UseAnAsyncThing(mock.Object);        mock.Setup(X => x.AnAsyncMethod(It.IsAny&所述;串GT;()));        。sut.DoThatAsyncOperation(测试)ContinueWith(Y => {});        //所以测试似乎通过这不会抛出Moq.MockExcpetion
        //但是它不运行
        mock.Verify(X => x.AnAsyncMethod(不及格));
    }

此测试是没有的await和异步关键字设置并通过精细。

是的xUnit和起订量这一预期的行为吗?


更新

感谢斯蒂芬的评论,我设法通过两个变化来解决的第一个考验。该测试现在返回任务,而不是无效,莫克也返回任务。

  [事实]
    公共异步任务The_test_will_pass_even_though_it_should_fail()
    {
        VAR模拟=新模拟< IDoStuffAsync>();
        VAR SUT =新UseAnAsyncThing(mock.Object);        mock.Setup(X => x.AnAsyncMethod(It.IsAny<串GT;()))ReturnAsync(真)。        等待sut.DoThatAsyncOperation(测试);        //这个现在失败,因为它应该
        mock.Verify(X => x.AnAsyncMethod(不及格));
    }


解决方案

更改单元测试方法,以返回任务而不是无效,它应该工作。为异步作废支持单元测试正在考虑在将来的版本

我详细描述异步单元测试不默认情况下我的博客上工作。 (我的博客示例使用MSTest的,但在所有其他的测试运行中存在同样的问题,其中的xUnit pre-1.9)。

I am trying to discover how to apply the async and await keywords to my xUnit tests. I am using xUnit 1.9 and Async CTP 1.3. Here is my test case

I have an interface which specifies one asynchronous method call

public interface IDoStuffAsync
{
    Task AnAsyncMethod(string value);
}

I have a class which consumes the interface and calls the async method

public class UseAnAsyncThing
{
    private readonly IDoStuffAsync _doStuffAsync;

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

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

In my tests I wish to check that the method DoThatAsyncOperation is calling the method with the correct value so I mock the interface and use the Moq to verify the call

    [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"));
    }

This test is using the async and await keywords. When it runs it erroneously passes as Moq should assert that the verify fails. Any code after the call to sut.DoThatAsyncOperation("test"); does not run

    [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"));
    }

This test is setup without the await and async keywords and passes fine.

Is this expected behavior for xUnit and Moq?


Update

Thanks for Stephen's comment I managed to fix the first test by making two changes. The test now returns a Task instead of void and the Mock also returns a Task.

    [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"));
    }

解决方案

Change your unit test method to return Task instead of void, and it should work. Support for async void unit tests is being considered for a future release.

I describe in detail why async unit tests don't work by default on my blog. (My blog examples use MSTest, but the same problems existed in every other test runner, including xUnit pre-1.9).

这篇关于的xUnit和起订量不支持异步 - 等待关键词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆