具有模拟延迟的集成测试调用

Integration testing calls with simulated delays

我正在测试 asp.net Core 2.2 WebApi 后端,它使用 EF Core 进行数据持久化。

该解决方案是使用具有 repository/service 模式的 CLEAN 架构设计的,使每个组件都可以单独测试。

我的集成测试(使用 XUnit 和 EF Core 内存数据库)需要测试以下情况:

  1. 用户发出一个请求并立即发出另一个相同的请求。
  2. 用户发出请求,15 秒后,发出另一个相同的请求。
  3. 用户发出请求,30 秒后发出另一个相同的请求。

这些案例中的每一个都有大约 5 个变体。现在,我在每个调用之间使用 Thread.Sleep(x) 调用来模拟此延迟。当然,这意味着我的集成测试需要 ages 才能完成。使用延迟是为了让存储库层在每次调用时保存一个 DateTime.UtcNow 值;服务层使用其值来执行某些业务逻辑决策。

我想知道的是,是否有一种方法可以使用测试框架 'simulating' 这些延迟,从而消除测试实际等待这个时间的需要,并且 欺骗 存储库层使用 DateTime.UtcNow 值,该值递增 x

谢谢!

抽象 DateTime 某些接口后面的访问

public interface IDateTime { 
    DateTime UtcNow { get; }

    //...other members as needed. eg: DateTime Now { get; }
} 

在测试时可以模拟它的行为。

生产实施会简单地包装实际的 DateTime

public class DefaultClock : IDateTime {
    public DateTime UtcNow => DateTime.UtcNow;

    //...
}

并在您的 DI 容器中注册

service.AddSingleton<IDateTime, DefaultClock>();

测试时,可以根据需要模拟抽象;

//Arrange
DateTime time;
DatTime.TryParse("2009-05-01 12:00:00", out time);

var mock = new Mock<IDateTime>(); //USING MOQ

mock.SetupSequence(_ => _.UtcNow)
    .Returns(time);                 //first call
    .Returns(time.AddSeconds(15))   //second call
    .Returns(time.AddSeconds(30));  //third call

IDateTime clock = mock.Object;

//...inject clock into subject under test