我正在遵循这个指南。我的 API 项目中有一个
Startup
,它使用 appsettings.json
配置文件。
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.ReadFrom.Configuration(Configuration)
.CreateLogger();
}
我正在看的特定部分是
env.ContentRootPath
。我做了一些挖掘,看起来我的 appsettings.json
实际上并未复制到 bin
文件夹,但这很好,因为 ContentRootPath
返回 MySolution\src\MyProject.Api\
,这是 appsettings.json
文件所在的位置。
所以在我的集成测试项目中我有这个测试:
public class TestShould
{
private readonly TestServer _server;
private readonly HttpClient _client;
public TestShould()
{
_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
_client = _server.CreateClient();
}
[Fact]
public async Task ReturnSuccessful()
{
var response = await _client.GetAsync("/monitoring/test");
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
Assert.Equal("Successful", responseString);
}
这基本上是从指南中复制和粘贴的。当我调试这个测试时,
ContentRootPath
实际上是MySolution\src\MyProject.IntegrationTests\bin\Debug\net461\
,这显然是测试项目的构建输出文件夹,并且appsettings.json
文件不在那里(是的,我在测试项目中有另一个appsettings.json
文件)本身),因此测试无法创建 TestServer
。
我尝试通过修改测试
project.json
文件来解决这个问题。
"buildOptions": {
"emitEntryPoint": true,
"copyToOutput": {
"includeFiles": [
"appsettings.json"
]
}
}
我希望这会将
appsettings.json
文件复制到构建输出目录,但它抱怨该项目缺少入口点的 Main
方法,将测试项目视为控制台项目。
我能做些什么来解决这个问题?我是不是做错了什么?
在ASP.NET.Core 2.0上进行集成测试,遵循MS指南,
您应该右键单击
appsettings.json
将其属性Copy to Output directory
设置为始终复制
现在你可以在输出文件夹中找到 json 文件,并使用
构建
TestServer
var projectDir = GetProjectPath("", typeof(TStartup).GetTypeInfo().Assembly);
_server = new TestServer(new WebHostBuilder()
.UseEnvironment("Development")
.UseContentRoot(projectDir)
.UseConfiguration(new ConfigurationBuilder()
.SetBasePath(projectDir)
.AddJsonFile("appsettings.json")
.Build()
)
.UseStartup<TestStartup>());
/// Ref: https://stackoverflow.com/a/52136848/3634867
/// <summary>
/// Gets the full path to the target project that we wish to test
/// </summary>
/// <param name="projectRelativePath">
/// The parent directory of the target project.
/// e.g. src, samples, test, or test/Websites
/// </param>
/// <param name="startupAssembly">The target project's assembly.</param>
/// <returns>The full path to the target project.</returns>
private static string GetProjectPath(string projectRelativePath, Assembly startupAssembly)
{
// Get name of the target project which we want to test
var projectName = startupAssembly.GetName().Name;
// Get currently executing test project path
var applicationBasePath = System.AppContext.BaseDirectory;
// Find the path to the target project
var directoryInfo = new DirectoryInfo(applicationBasePath);
do
{
directoryInfo = directoryInfo.Parent;
var projectDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, projectRelativePath));
if (projectDirectoryInfo.Exists)
{
var projectFileInfo = new FileInfo(Path.Combine(projectDirectoryInfo.FullName, projectName, $"{projectName}.csproj"));
if (projectFileInfo.Exists)
{
return Path.Combine(projectDirectoryInfo.FullName, projectName);
}
}
}
while (directoryInfo.Parent != null);
throw new Exception($"Project root could not be located using the application root {applicationBasePath}.");
}
参考:带有 WebHostBuilder 的 TestServer 无法读取 ASP.NET Core 2.0 上的 appsettings.json,但它可以在 1.1 上运行
appsettings.json
文件复制到输出目录。相反,它告诉测试项目 Web 应用程序的实际目录。
至于将
appsettings.json
复制到输出目录,我也设法让它工作。结合 dudu 的答案,我使用 include
而不是 includeFiles
,所以结果部分看起来像这样:
"buildOptions": {
"copyToOutput": {
"include": "appsettings.json"
}
}
我不太确定为什么会这样,但确实如此。我快速查看了文档,但找不到任何真正的差异,并且由于最初的问题已基本解决,所以我没有进一步查看。
删除测试
"emitEntryPoint": true
文件中的 project.json
。