AppSettings.json 用于 ASP.NET Core 中的集成测试
Posted
技术标签:
【中文标题】AppSettings.json 用于 ASP.NET Core 中的集成测试【英文标题】:AppSettings.json for Integration Test in ASP.NET Core 【发布时间】:2017-05-13 23:19:56 【问题描述】:我正在关注这个guide。我在使用appsettings.json
配置文件的API 项目中有一个Startup
。
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
方法,将测试项目视为控制台项目。
我能做些什么来解决这个问题?我做错了吗?
【问题讨论】:
【参考方案1】:删除测试project.json
文件中的"emitEntryPoint": true
。
【讨论】:
这消除了关于它缺少Main
的错误,但它没有将appsettings.json
复制到bin
目录中。【参考方案2】:
最后,我关注了这个guide,特别是页面底部的集成测试部分。这消除了将appsettings.json
文件复制到输出目录的需要。相反,它会告诉测试项目 Web 应用程序的实际目录。
至于将appsettings.json
复制到输出目录,我也设法让它工作。结合 dudu 的回答,我使用了 include
而不是 includeFiles
,所以生成的部分看起来像这样:
"buildOptions":
"copyToOutput":
"include": "appsettings.json"
我不完全确定为什么会这样,但确实如此。我快速浏览了文档,但找不到任何真正的差异,并且由于最初的问题已经基本解决,所以我没有进一步查看。
【讨论】:
据我了解:在测试期间,当您使用目标应用程序根目录作为内容根目录和/或基本路径(而不是测试输出目录)时,您的应用程序Startup
将使用自己的@987654328 @,就像在测试之外运行时一样。在这种情况下,将测试项目appsettings.json
复制到其输出目录将无效。根本不会读取该 json 文件。这是你的经历吗?
如何在 .NET.Core 2.0 中做到这一点? project.json
已弃用。
嗨@Kevin Lee 你能指定你使用的实际代码而不是指向指南吗?有时微软会在过去两年更改文档,谢谢【参考方案3】:
集成测试在ASP.NET.Core 2.0上关注MS guide,
您应该右键单击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://***.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.");
参考:TestServer w/ WebHostBuilder doesn't read appsettings.json on ASP.NET Core 2.0, but it worked on 1.1
【讨论】:
嗨@John_J 你也能帮忙回答这个问题吗?谢谢,***.com/questions/57318131/… 嗨@John_J ProjectDir 是什么?它是实际项目的路径,还是实际项目构建工件的路径,比如 bin-debug 类型的文件夹?请在回答中指定,谢谢 - 另外,如果您正在测试,如何指向原始应用程序启动? GetCurrentDirectory 是测试项目的目录,不是真正的项目吗? 嗨@JeremyWatkins,contentRoot
是您的 .csproj 文件所在的位置。我使用 ***.com/a/52136848/3634867 的“GetProjectPath”
@user11721944 ,作为方法描述,ProjectDir 是“获取我们希望测试的目标项目的完整路径”而不是测试项目目录。试试看吧:)以上是关于AppSettings.json 用于 ASP.NET Core 中的集成测试的主要内容,如果未能解决你的问题,请参考以下文章
.NET Core 应用程序中的 appsettings.json 与 appsettings.Environment.json
用 appsettings.Production.json 中的设置覆盖 appsettings.json 中的数组设置