MSTEST - 异步Testinitialize保证测试失败

cod*_*ter 13 .net c# tdd unit-testing asynchronous

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

这是在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);
    }
Run Code Online (Sandbox Code Playgroud)

任何想法?

Ste*_*ary 13

可能最简洁的方法是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);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 10

你的代码是正确的!

澄清这个答案是在最初的问题之后的 5 年零 2 个月。那时有 async[TestInitialize]可能是一个编译错误,但现在不是。

有可能有 async [TestInitialize], async[ClassInitialize]和 async[TestMethod]只是简单地使用 await。

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

private Category rootCategory;

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

[TestInitialize]在 each 之前运行[TestMethod],所以根据我在这里尝试测试的内容,最好只加载一次然后进行所有断言,而不是多次支付加载时间。但是您需要小心,以便测试不会相互影响以获得一致和正确的结果。

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


Had*_*ady 8

你想要做的是使用.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);
}
Run Code Online (Sandbox Code Playgroud)

  • 这不会编译.您不能在未使用`async`修饰符声明的方法中使用`await`关键字.第6行应该是:`Task <object> result = LongRunningMethod();` (3认同)

小智 7

只需为各种初始化调用(每个返回任务)创建一个任务数组,然后使用 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()
    {
    }
Run Code Online (Sandbox Code Playgroud)