【问题标题】:Start .NET Core Web API by code - multi platform (linux / windows)通过代码启动 .NET Core Web API - 多平台(linux/windows)
【发布时间】:2019-08-17 08:22:51
【问题描述】:

我正在为我的 Web API 编写单元测试(一切都使用 .Net Core 2.2 实现)。 对于这个测试,我必须实际向 Web API 发送一个请求。但是,我真的不知道如何通过代码启动 API。好像不能通过代码启动web服务。

所以我尝试了使用脚本的解决方法。这在 Windows 上运行良好,但 Linux 导致了一些问题。

dotnet run --project <pathToProject>

通常会启动 API。但是,在执行脚本后,一切都立即终止。创建的C#流程实例有ExitCode = 0HasExited = true

有人遇到过这样的问题吗?或者有什么想法?

提前致谢

【问题讨论】:

  • 我想知道为什么不直接测试控制器? (在您的测试类中注入)您使用的是 xunit 还是其他框架?

标签: c# linux asp.net-web-api asp.net-core .net-core


【解决方案1】:

如果我正确理解了您的问题,有一种非常简单的方法可以做到这一点。在Microsoft.AspNetCore.TestHostnampespace 中有一个TestServer 类,可以轻松地为您的API 启动测试服务器。但是,您需要注意一些事情,例如要加载什么配置,什么服务等等。这样做的背景是,您可能希望在测试时模拟一些服务,例如数据库存储库,并在内存集合或任何可能适合您的测试的东西中使用。

这是一个基本的实现。首先,在您要测试的 API 中,确保需要模拟的服务是通过 Startup 类中的虚拟方法注册的。

剥离ConfigureServices mehtod 的示例:

public void ConfigureServices(IServiceCollection services)
        {
            RegisterDatabase(services);

        }

并且在Startup.cs 中也有实现(我在这个例子中使用了Mongo):

protected virtual void RegisterDatabase(IServiceCollection services)
        {
            string mongoConnectionString = Configuration.GetConnectionString("DevCN");
            services.AddScoped<IMyDbProcessor, MyDbProcessor>(sp =>
            {
                var mongoClient = new MongoClient(mongoConnectionString);
                return new MyDbProcessor(mongoClient);
            });
        }

请注意,用于数据处理的类特定于我从中提取此示例的 API。

接下来在测试项目中(不管您使用什么测试运行程序或单元测试框架),您将创建一个 StartUp 类,您可以在其中覆盖数据库注册。例如,在此覆盖中,您可以注册模拟。

public class MyTestStartup : Startup
    {

        public MyTestStartup(IConfiguration configuration)
        {   
            Configuration = configuration;
        }

        protected override void RegisterDatabase(IServiceCollection services)
        {
                services.AddScoped<IMyDbProcessor>(db => new TestDbProcessor());
        }
    }

然后仍然在单元测试项目中,您可以创建一个类来保存您的测试服务器并配置您需要的任何内容。这是一个示例:

public class MyTestServer
    {
        //I add an HttpClient that will be used in the test methods to make the actual call
        internal HttpClient Client { get; set; }


        public MyTestServer()
        {
            IWebHostBuilder builder = new WebHostBuilder()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    IHostingEnvironment env = hostingContext.HostingEnvironment;
                    config.AddJsonFile("testsettings.json", optional: true)
                        .AddJsonFile($"testsettings.{env.EnvironmentName}.json", optional: true);
                })
                .UseStartup<MyTestStartup>();
            builder.UseSetting(WebHostDefaults.ApplicationKey, typeof(Program).GetTypeInfo().Assembly.FullName);
            var testServer = new TestServer(builder);
            Client = testServer.CreateClient();
        }
    }

这里特别注意typeof(Program).GetTypeInfo().Assembly.FullName)部分。 “程序”应在您的 API 中引用您的 Program.cs。 然后在单元测试类中,您可以使用该类的构造函数来创建一个新服务器并获取所需的客户端进行调用。

_server = new MyTestServer();
            _client = _server.Client;

现在您可以使用客户端调用您的 API。每次运行测试时,都会有一个测试服务器运行您的 API。 注意:如果您不想添加自定义配置(特定于您的测试环境),您可以简化 Web 服务器的创建。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 2021-01-23
    • 2020-12-20
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    相关资源
    最近更新 更多