猿问

通过代码启动.NET Core Web API——多平台(linux/windows)

我正在为我的 Web API 编写单元测试(一切都是使用 .Net Core 2.2 实现的)。对于此测试,我必须实际向 Web API 发送请求。但是,我真的不知道如何通过代码启动 API。您似乎无法通过代码启动网络服务。

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

dotnet run --project <pathToProject>

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

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


侃侃尔雅
浏览 139回答 1
1回答

郎朗坤

如果我正确理解你的问题,那么有一种非常简单的方法可以做到这一点。在Microsoft.AspNetCore.TestHost命名空间中,有一个TestServer类可以让您轻松地为您的 API 启动测试服务器。但是,有一些事情需要你注意,比如加载什么配置,加载什么服务等等。这样做的背景是,当您测试和使用内存集合或任何可能适合您的测试时,您可能想模拟一些服务,如数据库存储库。这是一个基本的实现。首先,在你要测试的API中,确保需要模拟的服务是通过Startup类中的虚方法注册的。剥离方法的示例ConfigureServices:public void ConfigureServices(IServiceCollection services)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RegisterDatabase(services);&nbsp; &nbsp; &nbsp; &nbsp; }并且实现也在Startup.cs(我在这个例子中使用Mongo):protected virtual void RegisterDatabase(IServiceCollection services)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; string mongoConnectionString = Configuration.GetConnectionString("DevCN");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; services.AddScoped<IMyDbProcessor, MyDbProcessor>(sp =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var mongoClient = new MongoClient(mongoConnectionString);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new MyDbProcessor(mongoClient);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; }请注意,数据处理类特定于我从中获取此示例的 API。接下来在测试项目中(不管您使用什么测试运行程序或单元测试框架),您将创建一个StartUp覆盖数据库注册的类。例如,在此覆盖中,您可以注册模拟。public class MyTestStartup : Startup&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public MyTestStartup(IConfiguration configuration)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Configuration = configuration;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; protected override void RegisterDatabase(IServiceCollection services)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; services.AddScoped<IMyDbProcessor>(db => new TestDbProcessor());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }然后仍然在单元测试项目中,您可以创建一个类来保存您的测试服务器并根据需要进行配置。这是一个看起来如何的示例:public class MyTestServer&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; //I add an HttpClient that will be used in the test methods to make the actual call&nbsp; &nbsp; &nbsp; &nbsp; internal HttpClient Client { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public MyTestServer()&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IWebHostBuilder builder = new WebHostBuilder()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .UseContentRoot(Directory.GetCurrentDirectory())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ConfigureAppConfiguration((hostingContext, config) =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IHostingEnvironment env = hostingContext.HostingEnvironment;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; config.AddJsonFile("testsettings.json", optional: true)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddJsonFile($"testsettings.{env.EnvironmentName}.json", optional: true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .UseStartup<MyTestStartup>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; builder.UseSetting(WebHostDefaults.ApplicationKey, typeof(Program).GetTypeInfo().Assembly.FullName);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var testServer = new TestServer(builder);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Client = testServer.CreateClient();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }这里要特别注意的typeof(Program).GetTypeInfo().Assembly.FullName)部分。“程序”应该Program.cs在您的 API 中引用您的。然后在单元测试类中,您可以使用该类的构造函数来创建一个新服务器并获取所需的客户端进行调用。_server = new MyTestServer();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _client = _server.Client;现在您可以使用客户端调用您的 API。每次运行测试时,都会有一个运行 API 的测试服务器。 注意:如果您不想添加自定义配置(特别针对您的测试环境),您可以简化 Web 服务器的创建。
随时随地看视频慕课网APP
我要回答