我只是在使用xUnit
和Moq
设置单元测试时遇到了问题。
方法TestMethod()
包含我要测试的逻辑。它是异步的,尽管返回Task
public class Testee
{
private readonly IDoSomething _doSomething;
public Testee(IDoSomething doSomething)
{
_doSomething = doSomething;
}
public async Task TestMethod()
{
await _doSomething.DoAsync(true); // throws NullReferenceException in Unit-Test
}
}
界面IDoSomething
如下
public interface IDoSomething
{
Task DoAsync(bool aboolean);
}
现在我可以像这样设置我的单元测试。
public class TesteeTest
{
[Fact]
public async Task MyTest()
{
var mock = new Mock<IDoSomething>();
mock.Setup(x => x.DoAsync(It.IsAny<bool>())).Verifiable();
var testee = new Testee(mock.Object);
await testee.TestMethod(); // Test breaks here because it throws an exception
mock.Verify(x => x.DoAsync(true), Times.Once);
mock.Verify(x => x.DoAsync(false), Times.Never);
}
}
为什么会出现此异常?
答案 0 :(得分:3)
mock.Setup()
缺少返回值,并返回null
。因此,在TestMethod()
中,Task
返回的_doSomething.DoAsync(true)
是null
。 null
等待着,当然会导致System.NullReferneceException
。
要解决此问题,建议您将.Returns(Task.CompletedTask)
添加到Mock-Setup中。
mock.Setup(x => x.DoAsync(It.IsAny<bool>())).Returns(Task.CompletedTask).Verifiable();
随着await
使用Awaiter-Pattern进行编译,现在有一个任务可以调用.GetAwaiter()
,以返回TaskAwaiter
。这些原则在这里有更好的解释: