unit test net unit-testing asp.net-core appsettings

unit-testing - .net core unit testing



Lea los valores json de las aplicaciones en.NET Core Test Project (5)

Mi aplicación web necesita leer las claves de la base de datos de documentos del archivo appsettings.json. He creado una clase con los nombres de las teclas y leyendo la sección ConfigureaServices() en ConfigureaServices() como:

public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfigurationRoot Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver()); services.AddSession(); Helpers.GetConfigurationSettings(services, Configuration); DIBuilder.AddDependency(services, Configuration); }

Estoy buscando formas de leer los valores clave en el proyecto de prueba.


Copie appSettings.json a su directorio raíz del proyecto de Prueba y marque su propiedad como Contenido y Copie si es más reciente .

var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables(); ConfigurationManager.Configuration = builder.Build();

ConfigurationManager es una clase y tiene una propiedad estática Configuration . De esta manera, toda la aplicación puede acceder a ella como ConfigurationManager.Configuration[<key>]


En el project.json de su proyecto de prueba, agregue las siguientes dependencias:

"dependencies": { "xunit": "2.2.0-beta2-build3300", "Microsoft.AspNetCore.TestHost": "1.0.0", "dotnet-test-xunit": "2.2.0-preview2-build1029", "BancoSentencas": "1.0.0-*" },

BancoSentencas es el proyecto que quiero probar. Los otros paquetes son de xUnit y el TestHost que será nuestro servidor en memoria.

Incluya también esta opción de compilación para appsettings.json:

"buildOptions": { "copyToOutput": { "include": [ "appsettings.Development.json" ] } }

En mi proyecto de prueba, tengo la siguiente clase de prueba:

public class ClasseControllerTeste : IClassFixture<TestServerFixture> { public ClasseControllerTeste(TestServerFixture fixture) { Fixture = fixture; } protected TestServerFixture Fixture { get; private set; } [Fact] public async void TestarRecuperarClassePorId() { using(var client = Fixture.Client) { var request = await Fixture.MyHttpRequestMessage(HttpMethod.Get, "/api/classe/1436"); var response = await client.SendAsync(request); string obj = await response.Content.ReadAsStringAsync(); ClasseModel classe = JsonConvert.DeserializeObject<ClasseModel>(obj); Assert.NotNull(classe); Assert.Equal(1436, classe.Id); } } }

Y también tengo la clase TestServerFixture que configurará el servidor en memoria:

public class TestServerFixture : IDisposable { private TestServer testServer; protected TestServer TestServer { get { if (testServer == null) testServer = new TestServer(new WebHostBuilder().UseEnvironment("Development").UseStartup<Startup>()); return testServer; } } protected SetCookieHeaderValue Cookie { get; set; } public HttpClient Client { get { return TestServer.CreateClient(); } } public async Task<HttpRequestMessage> MyHttpRequestMessage(HttpMethod method, string requestUri) { ... login stuff... ... Cookie = SetCookieHeaderValue.Parse(response.Headers.GetValues("Set-Cookie").First()); var request = new HttpRequestMessage(method, requestUri); request.Headers.Add("Cookie", new CookieHeaderValue(Cookie.Name, Cookie.Value).ToString()); request.Headers.Accept.ParseAdd("text/xml"); request.Headers.AcceptCharset.ParseAdd("utf-8"); return request; } public void Dispose() { if (testServer != null) { testServer.Dispose(); testServer = null; } } }

Así es como pruebo mi proyecto. Utilizo Startup.cs del proyecto principal y creo una copia desde appsettings.json en mi proyecto de prueba (appsettings.Development.json)


Esto se basa en la publicación del blog Usando archivos de configuración en .NET Core Unit Test Projects (escrito para .NET Core 1.0).

  1. Cree (o copie) el archivo appsettings.test.json en el directorio raíz del proyecto de prueba de Integración, y en las propiedades especifique "Crear acción" como Contenido y "Copiar si es más nuevo" en el Directorio de salida. Tenga en cuenta que es mejor tener un nombre de archivo (por ejemplo, appsettings.test.json ) diferente de appsettings.json normal, porque es posible que un archivo del proyecto principal anule el archivo del proyecto de prueba, si se usa el mismo nombre.

  2. Incluya el paquete NuGet del archivo de configuración JSON (Microsoft.Extensions.Configuration.Json) si aún no está incluido.

  3. En el proyecto de prueba crear un método,

    public static IConfiguration InitConfiguration() { var config = new ConfigurationBuilder() .AddJsonFile("appsettings.test.json") .Build(); return config; }

  4. Usa la configuración como de costumbre.

    var config = InitConfiguration(); var clientId = config["CLIENT_ID"]

Por cierto: también puede interesarle leer la configuración en la clase IOptions como se describe en Prueba de integración con IOptions <> en .NET Core :

var options = config.Get<MySettings>();


Honestamente, si realiza una prueba de unidad de una aplicación, debe tratar de aislar la clase que está probando de todas las dependencias, como llamar a otras clases, acceder al sistema de archivos, la base de datos, la red, etc. A menos que esté haciendo pruebas de integración o pruebas funcionales.

Dicho esto, para probar la aplicación de la unidad, es probable que desee simular estos valores de su archivo appsettings.json y simplemente probar su lógica.

Así que tu appsettings.json se vería así.

"DocumentDb": { "Key": "key1" }

A continuación, cree una clase de configuración.

public class DocumentDbSettings { public string Key { get; set; } }

Luego regístrelo en el método ConfigureServices() .

services.Configure<DocumentDbSettings>(Configuration.GetSection("DocumentDb"));

Entonces, por ejemplo, su controlador / clase podría verse así.

// ... private readonly DocumentDbSettings _settings; public HomeController(IOptions<DocumentDbSettings> settings) { _settings = settings.Value; } // ... public string TestMe() { return $"processed_{_settings.Key}"; }

Luego, en su proyecto de pruebas puede crear dicha clase de prueba unitaria.

public class HomeControllerTests { [Fact] public void TestMe_KeyShouldBeEqual_WhenKeyIsKey1() { // Arrange const string expectedValue = "processed_key1"; var configMock = Substitute.For<IOptions<DocumentDbSettings>>(); configMock.Value.Returns(new DocumentDbSettings { Key = "key1" // Mocking the value from your config }); var c = new HomeController(configMock); // Act var result = c.TestMe(); // Assert Assert.Equal(expectedValue, result); } }

Utilicé NSubstitute v2.0.0-rc para burlarme.


La solución de Suderson funcionó para mí cuando se modificó de la siguiente manera:

var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables(); IConfiguration config = builder.Build(); //Now, You can use config.GetSection(key) to get the config entries