异步方法延迟Moq返回不延迟

时间:2018-01-03 10:41:07

标签: c# unit-testing asynchronous async-await moq

在我的单元测试中,我尝试从我的接口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和我的存根类创建延迟有什么不同?

2 个答案:

答案 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