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

Tan*_*any 1 c# multithreading nunit fakeiteasy

我有一个方法:

public class MyClass
{
    public ILogger _logger;

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

和一个测试用例:

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

MustHaveHappened断言总是失败说

以下调用的断言失败:
MyClass.TestLogMethod <System.Object>(<Ignored>)
预期至少找到一次但没有对伪对象进行调用.

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

Cha*_*ger 5

你不是在等待完成TestLogMethod,所以你要在它发生之前验证它的期望.该Task会定于线程池,然后该方法将立即返回.这就是为什么你应该避免异步void方法.

更改方法以返回a,Task以便您有所需要await.您也可以删除大多数asyncawait对,因为它们是多余的:

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

然后await在你的测试中:

await testClass.TestLogMethod("Test Message");
Run Code Online (Sandbox Code Playgroud)

然后,当验证发生时,呼叫ILogger.Log将发生.