繁体   English   中英

用 TestServer 和 NSubstitute 改装

[英]Refit with TestServer and NSubstitute

我正在尝试使用 Refit 在 TestServer 上测试 Rest 接口,同时替换 DateTime.Now 以返回自定义时间。

我的改装界面如下所示:

public interface IMyApi
    {
        DateTime CurentTime();
        [Get("/api/...")]
        Task<ApiResponse<DateTime>> SomeOtherFunction();
    }

在我的实施中,我有

public class MyApi {
  public virtual DateTime CurrentTime { return DateTime.Now; } 
  ...
  public async Task<IActionResult> SomeOtherFunction() { return CurrentTime();  }
}

这可以很好地作为单元测试

var myMock = Substitute.ForPartsOf<MyApi>();
myMock.Configure().CurrentTime().Returns(..some fixed date..);
myMock.SomeOtherFunction();
// returns the fixed date

但是,当我使用 Refit 创建双胞胎并在 TestServer 上运行时,我想念如何让它工作,因为原来的 function 不断被调用:

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();

所以问题是,我如何使用模拟的 API 而不是原始的 api 创建 RestService.For<> ? 或者你有什么其他建议吗?

这个想法是我们需要替换 controller 工厂在运行时创建的 controller。 我发现这样做的最简单方法是:

  1. 在启动 class 的“ConfigureServices”中,告诉框架将 controller 存储在服务集合中。 我的现在看起来有点像这样:
        public void ConfigureServices(IServiceCollection services)
        {
            ...
            services.AddControllers().AddControllersAsServices()
                  .AddOtherThings(...)                                                       );
            ...
         }
  1. 将 controller 替换为模拟的 controller,在某个地方可以访问 controller 集合(例如在 WebHostBuilder 的 ConfigureTestServices 中):
    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"));

在这里玩游戏有点晚了,但是您是否尝试过使用 RefitSettings。 这是一个使用 MockHttpMessageHandler 的示例。 我以前用它来模拟 Refit 注入。

using var mockHttp = new MockHttpMessageHandler(); 
var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp };            
var apiServiceMock = RestService.For<IRealTimePayment>("https://api.github.com", settings);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM