MustHaveHappened Assert总是失败,因为在单独的线程上运行异步方法(Task.Run)

时间:2017-04-21 14:46:07

标签: c# multithreading nunit fakeiteasy

我有一个方法:

public class MyClass
{
    public ILogger _logger;

    public async void TestLogMethod(string msg)
    {
        await Task.Run(async ()=> await _logger.Log(msg));
    }
}

一个测试用例:

[Test]
public async Task TestLogMethod_LogMessage_Test()
{
    var fakeLogger = A.Fake<ILogger>();
    var testClass = new MyClass();
    testClass._logger = fakeLogger;

    testClass.TestLogMethod("Test Message");

    A.CallTo(() => fakeLogger.Log(A<string>._)).MustHaveHappened();
}

MustHaveHappened断言总是失败说

  

以下电话的断言失败:
     MyClass.TestLogMethod&LT; System.Object的&GT;(小于忽略&GT)
    预计会发现它至少一次但没有对伪造物体进行过调用。

很明显,_logger.Log()被调用,但为什么Asserting总是在这里失败?

1 个答案:

答案 0 :(得分:5)

你不是在等待TestLogMethod的完成,所以你要在它发生之前验证期望。将在线程池上安排Task,然后该方法将立即返回。这就是你应该avoid async void方法的原因。

更改方法以返回Task,以便您拥有await的内容。您也可以删除大多数asyncawait对,因为它们是多余的:

public Task TestLogMethod(string msg)
{
    return Task.Run(() => _logger.Log(msg));
}

然后await在你的测试中:

await testClass.TestLogMethod("Test Message");

然后在验证发生时,ILogger.Log的调用将会发生。