web-dev-qa-db-ja.com

ASP.NET Coreの統合テスト用AppSettings.json

私はこれをフォローしています ガイド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フォルダーにコピーされていないように見えますが、ContentRootPathMySolution\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メソッドを失い、テストプロジェクトをコンソールプロジェクトのように扱っていることを訴えます。

これを回避するにはどうすればよいですか?私は何か間違っていますか?

18
Kevin Lee

最後に、この ガイド 、特にIntegration Testingセクションに従ってページの下部に進みました。これにより、appsettings.jsonファイルを出力ディレクトリにコピーする必要がなくなります。代わりに、テストプロジェクトにWebアプリケーションの実際のディレクトリを伝えます。

appsettings.jsonを出力ディレクトリにコピーすることに関しては、それを機能させることもできました。 duduからの回答と組み合わせて、includeの代わりにincludeFilesを使用したため、結果のセクションは次のようになります。

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

これがなぜ機能するのか完全にはわかりませんが、機能します。ドキュメントをざっと見てみましたが、実際の違いを見つけることができませんでした。元の問題が本質的に解決されたので、これ以上は調べませんでした。

8
Kevin Lee

統合テストonASP.NET.Core 2.0follow 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}.");
}

参照: TestHost w/WebHostBuilderはASP.NET Core 2.0ではappsettings.jsonを読み取りませんが、1.1では動作しました

13
John_J

削除する "emitEntryPoint": trueテスト中project.jsonファイル。

1
dudu