I'm testing an asp.net Core 2.2 WebApi backend which uses EF Core for data persistance.
The solution is arquitected using CLEAN arquitecture with a repository/service pattern making every component individually testable.
My integration tests (using XUnit and EF Core in-memory database) need to test the following cases:
Each of these cases have about 5 variants each. Right now, I'm using a Thread.Sleep(x)
call in between each of the calls to simulate this delay. This, of course, means that my integration tests take ages to complete. The delays are used in order for the repository layer to save a DateTime.UtcNow
value when each of the calls is made; the value of which is used by the Service layer to perform some business-logic decisions.
What I'm wondering, is whether there is a way of 'simulating' these delays using the testing framework, removing the need for the tests to actually wait this time, and tricking the repository layer into using a DateTime.UtcNow
value which is incremented by x
.
Thanks you!
Abstract the DateTime
access behind some interface
public interface IDateTime {
DateTime UtcNow { get; }
//...other members as needed. eg: DateTime Now { get; }
}
That can be mocked to behave as desired when testing.
The production implementation would simple wrap the actual DateTime
public class DefaultClock : IDateTime {
public DateTime UtcNow => DateTime.UtcNow;
//...
}
and registered with your DI container
service.AddSingleton<IDateTime, DefaultClock>();
When testing, the abstraction can be mocked as needed;
//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