MSTEST - 异步Testinitialize保证测试失败

时间:2013-12-04 12:15:42

标签: c# .net unit-testing asynchronous tdd

只是想知道,如果有人这样想:

这是不正确的设计,要在TestInitialize中进行异步调用,因为TestInitialize必须在任何TestMethod之前发生。

这是否也可以以任何方式使用异步TestInitialize?

    private int val = 0;

    [TestInitialize]
    public async Task  TestMehod1()
    {
        var result = await LongRunningMethod();
        val = 10;
    }

    [TestMethod]
    public void  TestMehod2()
    {
        Assert.AreEqual(10, val);
    }

有什么想法吗?

4 个答案:

答案 0 :(得分:11)

可能最简单的方法是让TestInitialize 启动异步操作,如下所示:

[TestClass]
public class UnitTestAsync
{
    private Task<int> val = null;

    [TestInitialize]
    public void TestInitializeMethod()
    {
        val = TestInitializeMethodAsync();
    }

    private async Task<int> TestInitializeMethodAsync()
    {
        return await LongRunningMethod();
    }

    private async Task<int> LongRunningMethod()
    {
        await Task.Delay(20);
        return 10;
    }

    [TestMethod]
    public async Task TestMehod2()
    {
        Assert.AreEqual(10, await val);
    }
}

答案 1 :(得分:7)

您要做的是使用.Result.Wait()来同步阻止TestInitialize修饰的方法。您可以执行以下操作:

private int val = 0;

[TestInitialize]
public void TestMehod1()
{
    Task<object> result = await LongRunningMethod();
    result.Wait();

    val = 10;
}

[TestMethod]
public void  TestMehod2()
{
    Assert.AreEqual(10, val);
}

答案 2 :(得分:4)

只需为各种初始化调用(每个返回任务)创建一个任务数组,然后使用Task.WaitAll()

    [ClassInitialize()]
    public static void Initialize(TestContext context)
    {
        List<Task> tasks = new List<Task>();
        tasks.Add(InitializeMethod1());
        tasks.Add(InitializeMethod2());
        Task.WaitAll(tasks.ToArray());
    }

    public static async Task InitializeMethod1()
    {
    }

    public static async Task InitializeMethod2()
    {
    }

答案 3 :(得分:1)

您的代码正确!

要弄清楚这个答案,是在第一个问题之后的5年零2个月。那时,异步[TestInitialize]可能是编译错误,但如今并非如此。

只需使用await,就可以具有异步[TestInitialize],异步[ClassInitialize]和异步[TestMethod]

使用异步并正确等待可能是最干净的方法。我的代码中有类似以下内容的代码,在该代码中,我需要获取类别结构,以便能够测试我的类是否与我们拥有的类别结构配合良好。

private Category rootCategory;

[TestInitialize]
public async Task TestInitialize()
{
    var loader = new CategoryLoader();
    rootCategory = await loader.GetAllCategoriesAsync();
}

[TestInitialize]在每个[TestMethod]之前运行,因此根据我要在此处进行的测试,最好只加载一次然后进行所有声明,而不用为加载付费时间多次。但是您需要小心,以免测试相互影响,以获得一致和正确的结果。

请注意,由于我正在测试与外部服务的集成,因此这不再是单元测试。