在我的单元测试中,我尝试从我的接口Run()
模拟IPipeline
异步方法并模拟延迟,在类PipelineScheduler
中调用它
public interface IPipeline
{
Task Run();
}
测试Moq:
[SetUp]
public void SetUp()
{
_mockPipeline = new Mock<IPipeline>();
_mockPipeline.Setup(x => x.Run()).Returns(async () =>
{
await Task.Delay(3000);
});
_scheduler = new PipelineScheduler(_mockPipeline.Object);
}
然而,当我运行测试和调试时,模拟方法被称为
await _pipeline.Run().ConfigureAwait(false);
没有延迟,立即在此行之后继续执行。
但是如果我用存根类替换模拟,延迟工作正常。
private class MockPipeline : IPipeline
{
public async Task Run()
{
await Task.Delay(3000);
}
}
[SetUp]
public void SetUp()
{
_mockPipeline = new MockPipeline();
_scheduler = new PipelineScheduler(_mockPipeline);
}
所以我想问的问题是,与我如何使用moq和我的存根类创建延迟有什么不同?
答案 0 :(得分:4)
不同之处在于设置配置不正确。
返回任务即:.Returns(Task.Delay(3000));
是设置表现所需的全部内容。之前的设置很火,忘了async void
这就是上一个例子没有等待并立即继续的原因。
以下最小示例演示了如何设置模拟
[TestClass]
public class MyTestClass {
[TestMethod]
public async Task MyTestMethod() {
//Arrange
var _mockPipeline = new Mock<IPipeline>();
_mockPipeline.Setup(x => x.Run()).Returns(Task.Delay(3000)).Verifiable();
var sut = new PipelineScheduler(_mockPipeline.Object);
//Act
await sut.MethodUnderTest();
//Assert
_mockPipeline.Verify();
}
}
public interface IPipeline {
Task Run();
}
public class PipelineScheduler {
private IPipeline _pipeline;
public PipelineScheduler(IPipeline pipeline) {
this._pipeline = pipeline;
}
public async Task MethodUnderTest() {
await _pipeline.Run().ConfigureAwait(false);
}
}
运动时,测试会延迟3秒钟。
答案 1 :(得分:0)
一个老问题,但我只是遇到了问题,正确的方法是不被接受的答案。正确的方法是在返回中使用一个函数。
即
.Returns(() => Task.Delay(3000))
在没有() =>
的情况下,“延迟”仅应用一次,即使您进行了多个顺序调用(例如执行此操作),也是如此:
await _pipeline.Run().ConfigureAwait(false);
await _pipeline.Run().ConfigureAwait(false);
await _pipeline.Run().ConfigureAwait(false);
在dotnetfiddle.net上查看此reproduction