AppSettings.json 用于 ASP.NET Core 中的集成测试

问题描述 投票:0回答:3

我正在遵循这个指南。我的 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
方法,将测试项目视为控制台项目。

我能做些什么来解决这个问题?我是不是做错了什么?

c# configuration asp.net-core integration-testing appsettings
3个回答
21
投票

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 上运行


10
投票

最后,我遵循了这个指南,特别是集成测试部分。这样就无需将

appsettings.json
文件复制到输出目录。相反,它告诉测试项目 Web 应用程序的实际目录。

至于将

appsettings.json
复制到输出目录,我也设法让它工作。结合 dudu 的答案,我使用
include
而不是
includeFiles
,所以结果部分看起来像这样:

"buildOptions": {
    "copyToOutput": {
        "include": "appsettings.json"
    }
}

我不太确定为什么会这样,但确实如此。我快速查看了文档,但找不到任何真正的差异,并且由于最初的问题已基本解决,所以我没有进一步查看。


1
投票

删除测试

"emitEntryPoint": true
文件中的
project.json

© www.soinside.com 2019 - 2024. All rights reserved.