首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Net核心-集成测试- TestServer -真正的http连接

Net核心-集成测试- TestServer -真正的http连接
EN

Stack Overflow用户
提问于 2019-11-08 09:43:25
回答 1查看 1.5K关注 0票数 1

我们有几个.NET核心微服务/ API,我们希望做一些集成测试。因此,我们遵循教程,它工作很好,除了一种情况。

假设我有3个API,所以有3个"TestServer“实例,每个实例都有自己的HttpClient可连接!

我展示了创建TestServer的方式:

代码语言:javascript
复制
    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:

代码语言:javascript
复制
        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 =新Uri("http://localhost:5000");

真正的问题是,一些微服务通过这种方式创建自己的HttpClient,以便与其他API进行通信!它们是通过appsettings.json文件设置的,并试图连接到正常和真实的http服务器,而不是"TestServer“服务器!

你有办法解决这个问题吗?

谢谢

EN

回答 1

Stack Overflow用户

发布于 2019-11-08 14:22:13

这不是这么回事。集成测试是对组成一个应用程序的组件套件的测试。如果您正在测试Api1,那么您不需要旋转Api2和Api3的实例,而是对它们进行嘲弄,以便它们以已知和可预测的方式运行。如果使用实际实例,甚至测试实例,那么Api2中的失败可能会导致Api1测试失败,尽管Api1没有什么问题。

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

代码语言:javascript
复制
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

代码语言:javascript
复制
services.AddHttpClient<IApi2Service, Api2Service>(c =>
{
    c.BaseAddress = new Uri(Configuration["Api2BaseAddress"]);
});

最后,在Api1中需要与Api2交互的类(可能是控制器)中,您需要:

代码语言:javascript
复制
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实例适当地返回到您正在测试的内容中。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58764032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档