Estoy siguiendo esta guía. Tengo un Startup en el proyecto API que usa un archivo de configuración 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();
    }

La parte particular que estoy viendo es el env.ContentRootPath. Investigué un poco y parece que mi appsettings.json en realidad no se copia en la carpeta bin, pero eso está bien ya que ContentRootPath está devolviendo MySolution\src\MyProject.Api\, que es donde el Se encuentra el archivo appsettings.json.

Entonces, en mi proyecto de prueba de integración tengo esta prueba:

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

Esto es básicamente copiar y pegar de la guía. Cuando depuro esta prueba, ContentRootPath es en realidad MySolution\src\MyProject.IntegrationTests\bin\Debug\net461\, que obviamente es la carpeta de salida de compilación para el proyecto de prueba y nuevamente el archivo appsettings.json no está allí (sí, tengo otro {{ X3}} en el proyecto de prueba en sí), por lo que la prueba falla al crear el TestServer.

Intenté solucionar esto modificando el archivo de prueba project.json.

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

Esperaba que esto copiara el archivo appsettings.json en el directorio de salida de la compilación, pero se queja de que al proyecto le falta un método Main para un punto de entrada, tratando el proyecto de prueba como un proyecto de consola.

¿Qué puedo hacer para evitar esto? ¿Estoy haciendo algo mal?

18
Kevin Lee 29 dic. 2016 a las 18:51

3 respuestas

La mejor respuesta

Al final, seguí esta guía, específicamente la sección Pruebas de integración hacia la parte inferior de la página. Esto elimina la necesidad de copiar el archivo appsettings.json en el directorio de salida. En cambio, le dice al proyecto de prueba el directorio real de la aplicación web.

En cuanto a copiar el appsettings.json en el directorio de salida, también logré que funcione. En combinación con la respuesta de dudu , utilicé include en lugar de includeFiles para que la sección resultante se vea así:

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

No estoy completamente seguro de por qué esto funciona, pero lo hace. Eché un vistazo rápido a la documentación pero no pude encontrar ninguna diferencia real y, dado que el problema original se resolvió esencialmente, no busqué más.

8
Kevin Lee 16 oct. 2017 a las 09:17

Prueba de integración en ASP.NET.Core 2.0 siga Guía de MS,

Debe hacer clic con el botón derecho en appsettings.json establecer su propiedad Copy to Output directory en Copiar siempre

Y ahora puede encontrar el archivo json en la carpeta de salida y compilar TestServer con

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 w / WebHostBuilder no lee appsettings.json en ASP.NET Core 2.0, pero trabajado en 1.1

14
John_J 5 ago. 2019 a las 03:34

Elimine "emitEntryPoint": true en el archivo de prueba project.json.

1
dudu 18 ene. 2017 a las 09:02