Xamarin中的NUnit异步测试不起作用

Jos*_*osh 4 c# mono nunit async-await xamarin

我是C#世界的新手,试图给Xamarin一个评价.我一直在制作一个小型的web api库,到目前为止它一直很顺利,但现在我正在尝试测试网络组件,我遇到了一些麻烦.

OS:           OS X 10.9.1
Xamarin:      4.2.2 (build 2)
Library:      PCL targeting 4.0 (Profile158)
Nunit target: Mono / .NET 4.5
Run Code Online (Sandbox Code Playgroud)

类/方法:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Http;

namespace LibTest
{
    public class AsyncTest
    {
        public async Task<string> DoTest()
        {
            return await new HttpClient().GetStringAsync( "http://www.reddit.com/.json?limit=1" );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

NUnit测试类/案例:

using System;
using NUnit.Framework;
using LibTest;

namespace LibTestTests
{
    [TestFixture]
    public class LibTestTest
    {
        [Test]
        public async void TempTest()
        {
            string data = await new AsyncTest().DoTest();

            Assert.IsNotNull( data );
            Assert.IsNull( data );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的所有其他测试似乎都在工作(解析等),但是这个测试恰好是正确的,就好像它已经过去一样,但我看不出它是如何产生的,带有矛盾的断言.

目前不支持,还是我的实施不正确?

如果我使用ContinueWith()/ 与它同步Wait(),它会按预期工作,但显然我不想在我的库中有重复的实现,只是为了通过测试.

Ste*_*ary 9

NUnit确实支持async Task单元测试; 不幸的是,Xamarin使用的是较旧版本的NUnit.但是,我不建议直接同步阻塞任务,因为这会使错误路径测试变得复杂(异常包含在中AggregateException).

我的AsyncEx库中有一个AsyncContext类型可以这样使用:

[Test]
public void TempTest()
{
    AsyncContext.Run(async () =>
    {
        string data = await new AsyncTest().DoTest();

        Assert.IsNotNull( data );
        Assert.IsNull( data );
    });
}
Run Code Online (Sandbox Code Playgroud)


Ser*_*rvy 6

你有一个async void方法.无论何时使用它都应该是一个大红旗.

TempTest击到第一个,await它就会返回到来电者.其余的代码运行,但从调用者的角度来看,方法已经完成,并且调用者无法知道方法何时结束,它抛出的任何异常,任何失败的断言等.

当您同步等待时,您当然要确保调用此方法的线程抛出异常,而不是在测试框架无法观察到的其他位置的某个其他线程中抛出异常.

为了正确测试异步方法,测试框架确实需要设计为支持它,真的.它应该能够处理返回a的方法Task,并根据其结果进行操作Task.如果这不是一个选项,您需要手动完成这项工作.理想情况下,要保持正确的异步,而不是等待任何任务,您应该设置自己的消息泵(请参阅此处的示例),它将能够提取消息,直到顶级操作完成,从而允许您在同步方法中运行异步代码.