Net Core-集成测试-TestServer-真正的http连接

我们有几个.NET Core微服务/ API,我们希望进行一些集成测试。 因此,我们遵循了这些教程,除一种情况外,它都能正常工作。

想象一下,我有3个API,因此有3个“ TestServer”实例,每个实例都有自己的HttpClient来连接!

我展示了创建TestServer的方式:

    private TestServer SetupAPI<TStartup>(string path,string uri) where TStartup : class
    {
        string rootPath = Path.Join(_rootPath,"path");

        var hostBuilder = WebHost.CreateDefaultBuilder()
            .UseUrls(uri)
            .UseIISIntegration()
            //.ConfigureServices(services => services.AddSecurityHeaders())
            .UseContentRoot(rootPath)
            .UseEnvironment("Development")
            .ConfigureAppConfiguration(cb =>
            {
                cb.AddJsonFile("appsettings.json",optional: false)
                //.AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional: true)
                .AddEnvironmentVariables();
            })
            .UseStartup<TStartup>();

        TestServer server = new TestServer(hostBuilder);
        server.BaseAddress = new Uri(uri);

        return server;
    }

我展示了如何创建HttpClient:

        client = ArtistsServer.Createclient();
        client.BaseAddress = new Uri("http://localhost:5000");
        client.DefaultRequestHeaders.accept.Clear();
        client.DefaultRequestHeaders.accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

它运行良好,但是当我尝试以这种方式创建新的HttpClient时,它失败了:     HttpClient httpClient =新的HttpClient();     httpClient.BaseAddress = new Uri(“ http://localhost:5000”);

真正的问题是某些微服务以这种方式创建自己的HttpClient以便与其他API通信!它们是通过appsettings.json文件设置的,并尝试连接到普通的真实HTTP服务器,而不是“ TestServer”服务器!

您有解决此问题的想法吗?

谢谢

mengzai8888 回答:Net Core-集成测试-TestServer-真正的http连接

这不是这样的。集成测试是对组成单个应用程序的组件套件的测试。如果要测试Api1,则不会启动Api2和Api3的实例。您嘲笑那些,以便它们以已知且可预测的方式运行。如果您使用的是真实实例,甚至是 test 实例,那么即使Api1没问题,Api2的失败也可能导致您对Api1的测试失败。

因此,要使Api1与Api2通信,您需要一个HttpClient来进行请求。 HttpClient应该由IHttpClientFactory提供,并注入注册为类型化客户端的服务类中。在此服务类上,您将添加与API调用相对应的方法。为了可测试,此服务类应实现一个接口,然后应在需要使用此API时注入该接口。大致如下:

public interface IApi2Service
{
    Task<Foo> GetFooByIdAsync(int id);
}

public class Api2Service : IApi2Service
{
    private readonly HttpClient _client;

    public Api2Service(HttpClient client)
    {
        _client = client;
    }

    public async Task<Foo> GetFooByIdAsync(int id)
    {
        // use _client to make the API call
    }
}

然后,在Startup.ConfigureServices中:

services.AddHttpClient<IApi2Service,Api2Service>(c =>
{
    c.BaseAddress = new Uri(Configuration["Api2BaseAddress"]);
});

最后,在需要与Api2进行交互的Api1中的类(可能是控制器)中,您可以执行以下操作:

public class SomeApi1Controller : ControllerBase
{
    private readonly IApi2Service _api2Service;

    public SomeApi1Controller(IApi2Service api2Service)
    {
        _api2Service = api2Service;
    }

    public async Task<IActionResult> SomeAction()
    {
        var foo = await _api2Service.GetFooByIdAsync(1);
    }
}

现在,在正确设置代码之后,您只需将其嵌入Api2Service的测试实现中,并存入GetFooByIdAsync方法即可简单地返回测试Foo实例,而不是实际上通过HttpClient调用Api2。这样,您便确切知道将返回什么,并且可以适当地设计测试,并根据您要测试的内容返回不同类型的Foo实例。

本文链接:https://www.f2er.com/3138997.html

大家都在问