I am trying to use Refit to test a Rest interface on TestServer, while replacing the DateTime.Now to return custom time.
My refit interface looks something like this:
public interface IMyApi
{
DateTime CurentTime();
[Get("/api/...")]
Task<ApiResponse<DateTime>> SomeOtherFunction();
}
and in my implementation, I have
public class MyApi {
public virtual DateTime CurrentTime { return DateTime.Now; }
...
public async Task<IActionResult> SomeOtherFunction() { return CurrentTime(); }
}
This works fine as a Unit test
var myMock = Substitute.ForPartsOf<MyApi>();
myMock.Configure().CurrentTime().Returns(..some fixed date..);
myMock.SomeOtherFunction();
// returns the fixed date
However I am missing how to get this to work when I create the twin using Refit and running on TestServer, since the original function keeps getting called:
var myMock = Substitute.ForPartsOf<IMyApi>();
myMock.Configure().CurrentTime().Returns(..some fixed date..);
var myServer = new TestServer(builder: ... );
// how do I connect to the invokation below?
var client = RestService.For<IMyApi>(myServer.CreateClient());
client.SomeOtherFunction();
So question is, how do I have the RestService.For<> created out of the mocked API rather than the original api? Or do you have any other suggestions?
The idea is that we need to replace the controller that is created at run time by the controller factory. The easiest way I have found to do this is:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddControllers().AddControllersAsServices()
.AddOtherThings(...) );
...
}
var toRemove = svc.FirstOrDefault(d => d.ServiceType == typeof(MyApi));
svc.Remove(toRemove);
var c = Substitute.ForPartsOf<MyApi>(new object[] { ...constructor params... });
svc.AddScoped(controller => c);
controller.Configure().CurrentTime().Returns(DateTime.Parse("1/1/2001 10:00:00"));