C# 具有模拟延迟的集成测试调用
我正在测试一个asp.net Core 2.2 WebApi后端,它使用EF Core实现数据持久性 该解决方案使用干净的体系结构和存储库/服务模式实现,使每个组件都可以单独测试 我的集成测试(使用XUnit和EF Core内存数据库)需要测试以下情况:C# 具有模拟延迟的集成测试调用,c#,.net-core,integration-testing,asp.net-core-webapi,xunit,C#,.net Core,Integration Testing,Asp.net Core Webapi,Xunit,我正在测试一个asp.net Core 2.2 WebApi后端,它使用EF Core实现数据持久性 该解决方案使用干净的体系结构和存储库/服务模式实现,使每个组件都可以单独测试 我的集成测试(使用XUnit和EF Core内存数据库)需要测试以下情况: 用户发出一个请求并立即发出另一个相同的请求 用户发出一个请求,15秒后,发出另一个相同的请求 用户发出一个请求,30秒后,发出另一个相同的请求 每个病例各有5个变种。现在,我正在使用一个Thread.Sleep(x)调用来模拟这种延迟。当然,这
Thread.Sleep(x)
调用来模拟这种延迟。当然,这意味着我的集成测试需要很长时间才能完成。延迟用于存储库层在每次调用时保存DateTime.UtcNow
值;服务层使用其值来执行一些业务逻辑决策
我想知道的是,是否有一种方法可以使用测试框架来“模拟”这些延迟,从而消除测试实际等待这一次的需要,并诱使存储库层使用一个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>();
service.AddSingleton();
测试时,可以根据需要模拟抽象
//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
//排列
日期时间;
DatTime.TryParse(“2009-05-01 12:00:00”,超时);
var mock=new mock()//使用最小起订量
mock.SetupSequence(=>uCnow)
.返回(时间)//第一个电话
.Returns(time.AddSeconds(15))//第二次调用
.返回(time.AddSeconds(30))//第三次呼叫
IDateTime时钟=mock.Object;
//…将时钟注入受测对象
在一些接口接口IClock{DateTime UtcNow{get;}}}
后面抽象日期时间
访问,在测试时可以模拟该接口,使其按需要运行。这取决于时间范围的含义。如果你只是想知道将来某个时候会发生什么,那么@Nkosi是对的:你可以模拟时钟,并将时间设置为未来的时间。然而,在这里,您很可能正在寻找一种并发或类似并发的类型,在这种情况下,您实际上需要实时地将调用隔开。因此,您要么接受更长的测试时间,要么将其移动到不同的(通常是手动的)测试层。例如,它可能由实际的UAT人员运行。在这种情况下,测试时间本身并不是什么大问题。只有当它是您的CI管道的一部分时才有问题。@Nkosi,这是个好主意!如果您希望我将其设置为已接受,请将其作为答案发布。@ChrisPratt,我们正在查看并发情况/行为,但由于所有内容的结构,测试并发调用/幂等性问题在“案例1”中处理,这不会增加测试时间。其余的测试处理幂等性问题,但有些不同,这些测试将与建议的日期时抽象解决方案兼容。是的,问题出现在我们的CI/CD管道上。我有一个政策,任何PR必须首先通过一个测试流水线,这真的减慢了事情。还考虑了NotoTiMe库,它基本上是为了这个而在CLR类型中有很多其他缺陷。但是现在我更愿意添加一个我完全控制的自定义接口,而不是向解决方案添加另一个依赖项。根据上面的答案,依赖NodaTime而不是实现自定义界面是否有任何“隐藏”优势?取决于应用程序的需要。它比CLR类型更能处理i18n需求。你可以做实际的日历计算,用实际的时区来代替偏移量,在偏移量中,像DST这样的东西会让你很难受。