it-swarm.com.de

AppSettings.json für den Integrationstest in ASP.NET Core

Ich folge diesem Guide . Ich habe eine Startup im API-Projekt, das eine appsettings.json-Konfigurationsdatei verwendet.

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();
    }

Der spezielle Teil, den ich mir anschaue, ist der env.ContentRootPath. Ich habe ein bisschen herumgegraben und es sieht so aus, als würde mein appsettings.json nicht wirklich in den bin-Ordner kopiert werden, aber das ist in Ordnung, da ContentRootPathMySolution\src\MyProject.Api\ zurückgibt, wo sich die appsettings.json-Datei befindet.

In meinem Integrationstestprojekt habe ich diesen Test:

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);
    }

Dies ist im Grunde Kopieren und Einfügen aus der Anleitung. Wenn ich diesen Test debugge, ist ContentRootPath tatsächlich MySolution\src\MyProject.IntegrationTests\bin\Debug\net461\, was offensichtlich der Build-Ausgabeordner für das Testprojekt ist und wieder die appsettings.json-Datei nicht vorhanden ist (ja, ich habe eine andere appsettings.json-Datei im Testprojekt selbst) test schlägt beim Erstellen der TestServer fehl.

Ich habe versucht, dies zu umgehen, indem ich die project.json-Testdatei modifizierte.

"buildOptions": {
    "emitEntryPoint": true,
    "copyToOutput": {
        "includeFiles": [
            "appsettings.json"
       ]
    }
}

Ich habe gehofft, dass dies die appsettings.json-Datei in das Build-Ausgabeverzeichnis kopieren würde, aber es beschwert sich, dass das Projekt die Main -Methode für einen Einstiegspunkt fehlt und das Testprojekt wie ein Konsolenprojekt behandelt.

Was kann ich dagegen tun? Mache ich etwas falsch?

16
Kevin Lee

Am Ende folgte ich diesem guide , insbesondere dem Abschnitt Integration Testing am Ende der Seite. Dadurch muss die appsettings.json-Datei nicht mehr in das Ausgabeverzeichnis kopiert werden. Stattdessen teilt es dem Testprojekt das tatsächliche Verzeichnis der Webanwendung mit.

Beim Kopieren des appsettings.json in das Ausgabeverzeichnis ist es mir auch gelungen, dies zu erreichen. Zusammen mit der Antwort von dudu habe ich include anstelle von includeFiles verwendet, damit der resultierende Abschnitt in etwa so aussieht:

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

Ich bin nicht ganz sicher, warum das funktioniert, aber es funktioniert. Ich habe mir die Dokumentation kurz angeschaut, konnte aber keine echten Unterschiede feststellen und da das ursprüngliche Problem im Wesentlichen gelöst wurde, habe ich nicht weiter nachgesehen.

8
Kevin Lee

Integrationstest auf ASP.NET.Core 2.0 follow MS guide ,

Sie sollten mit der rechten Maustaste auf appsettings.json Klicken und die Eigenschaft Copy to Output directory Auf setzen. Immer kopieren

Und jetzt können Sie die JSON-Datei im Ausgabeordner finden und TestServer mit erstellen

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}.");
}

Ref: TestServer mit WebHostBuilder liest die Datei appsettings.json unter ASP.NET Core 2.0 nicht, hat jedoch unter 1.1 funktioniert

13
John_J

Entfernen Sie "emitEntryPoint": true in der Test project.json-Datei.

1
dudu