Share via


Özel ASP.NET Core ara yazılımını test etme

Tarafından Chris Ross

Ara yazılım ile TestServeryalıtımlı olarak test edilebilir. Şunları yapmanızı sağlar:

  • Yalnızca test etmeniz gereken bileşenleri içeren bir uygulama işlem hattının örneğini oluşturun.
  • Ara yazılım davranışını doğrulamak için özel istekler gönderin.

Avantajlar:

  • İstekler ağ üzerinden seri hale getirilmeyip bellek içinde gönderilir.
  • Bu, bağlantı noktası yönetimi ve HTTPS sertifikaları gibi ek endişeleri önler.
  • Ara yazılımdaki özel durumlar doğrudan çağrı testine geri akabilir.
  • gibi HttpContextsunucu veri yapılarını doğrudan testte özelleştirmek mümkündür.

TestServer'i ayarlama

Test projesinde bir test oluşturun:

  • kullanan TestServerbir konak oluşturun ve başlatın.

  • Ara yazılımının kullandığı tüm gerekli hizmetleri ekleyin.

  • NuGet paketi için Microsoft.AspNetCore.TestHost projeye bir paket başvurusu ekleyin.

  • İşlem işlem hattını test için ara yazılımı kullanacak şekilde yapılandırın.

    [Fact]
    public async Task MiddlewareTest_ReturnsNotFoundForRequest()
    {
        using var host = await new HostBuilder()
            .ConfigureWebHost(webBuilder =>
            {
                webBuilder
                    .UseTestServer()
                    .ConfigureServices(services =>
                    {
                        services.AddMyServices();
                    })
                    .Configure(app =>
                    {
                        app.UseMiddleware<MyMiddleware>();
                    });
            })
            .StartAsync();
    
        ...
    }
    

Dekont

.NET uygulamalarına paket ekleme hakkında yönergeler için, Paket tüketimi iş akışında (NuGet belgeleri)paketleri yüklemek ve yönetmek altındaki makalelere bakın. NuGet.org'da doğru paket sürümlerini onaylayın.

HttpClient ile istek gönderme

kullanarak HttpClientbir istek gönderin:

[Fact]
public async Task MiddlewareTest_ReturnsNotFoundForRequest()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .ConfigureServices(services =>
                {
                    services.AddMyServices();
                })
                .Configure(app =>
                {
                    app.UseMiddleware<MyMiddleware>();
                });
        })
        .StartAsync();

    var response = await host.GetTestClient().GetAsync("/");

    ...
}

Sonucu onaylar. İlk olarak, bir onaylama işlemini beklediğiniz sonucun tam tersi yapın. Hatalı pozitif onay ile yapılan ilk çalıştırma, ara yazılım doğru performans sergilediğinde testin başarısız olduğunu onaylar. Testi çalıştırın ve testin başarısız olduğunu onaylayın.

Aşağıdaki örnekte, kök uç nokta istendiğinde ara yazılım bir 404 durum kodu (Bulunamadı) döndürmelidir. ile ilk test çalıştırmasını Assert.NotEqual( ... );yapın ve başarısız olmalıdır:

[Fact]
public async Task MiddlewareTest_ReturnsNotFoundForRequest()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .ConfigureServices(services =>
                {
                    services.AddMyServices();
                })
                .Configure(app =>
                {
                    app.UseMiddleware<MyMiddleware>();
                });
        })
        .StartAsync();

    var response = await host.GetTestClient().GetAsync("/");

    Assert.NotEqual(HttpStatusCode.NotFound, response.StatusCode);
}

Ara yazılımı normal çalışma koşulları altında test etmek için onaylamayı değiştirin. Son testte kullanılır Assert.Equal( ... );. Geçtiğini onaylamak için testi yeniden çalıştırın.

[Fact]
public async Task MiddlewareTest_ReturnsNotFoundForRequest()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .ConfigureServices(services =>
                {
                    services.AddMyServices();
                })
                .Configure(app =>
                {
                    app.UseMiddleware<MyMiddleware>();
                });
        })
        .StartAsync();

    var response = await host.GetTestClient().GetAsync("/");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

HttpContext ile istek gönderme

Test uygulaması SendAsync(Action<HttpContext>, CancellationToken) kullanarak da istek gönderebilir. Aşağıdaki örnekte ara yazılım tarafından işlendiğinde https://example.com/A/Path/?and=query çeşitli denetimler yapılır:

[Fact]
public async Task TestMiddleware_ExpectedResponse()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .ConfigureServices(services =>
                {
                    services.AddMyServices();
                })
                .Configure(app =>
                {
                    app.UseMiddleware<MyMiddleware>();
                });
        })
        .StartAsync();

    var server = host.GetTestServer();
    server.BaseAddress = new Uri("https://example.com/A/Path/");

    var context = await server.SendAsync(c =>
    {
        c.Request.Method = HttpMethods.Post;
        c.Request.Path = "/and/file.txt";
        c.Request.QueryString = new QueryString("?and=query");
    });

    Assert.True(context.RequestAborted.CanBeCanceled);
    Assert.Equal(HttpProtocol.Http11, context.Request.Protocol);
    Assert.Equal("POST", context.Request.Method);
    Assert.Equal("https", context.Request.Scheme);
    Assert.Equal("example.com", context.Request.Host.Value);
    Assert.Equal("/A/Path", context.Request.PathBase.Value);
    Assert.Equal("/and/file.txt", context.Request.Path.Value);
    Assert.Equal("?and=query", context.Request.QueryString.Value);
    Assert.NotNull(context.Request.Body);
    Assert.NotNull(context.Request.Headers);
    Assert.NotNull(context.Response.Headers);
    Assert.NotNull(context.Response.Body);
    Assert.Equal(404, context.Response.StatusCode);
    Assert.Null(context.Features.Get<IHttpResponseFeature>().ReasonPhrase);
}

SendAsync soyutlamaları kullanmak yerine nesnenin HttpContext doğrudan yapılandırılmasını HttpClient sağlar. Yalnızca sunucuda bulunan HttpContext.Items veya HttpContext.Features gibi yapıları işlemek için kullanın SendAsync.

404 - Bulunamadı yanıtı için test edilen önceki örnekte olduğu gibi, önceki testteki her Assert deyimin tersini denetleyin. Denetim, ara yazılım normal çalıştığında testin doğru şekilde başarısız olduğunu onaylar. Hatalı pozitif testin çalıştığını onayladıktan sonra, testin beklenen koşulları ve değerlerinin son Assert deyimlerini ayarlayın. Testin başarılı olduğunu onaylamak için yeniden çalıştırın.

İstek yolları ekleme

Test HttpClientkullanılarak yapılandırma tarafından ek yollar eklenebilir:

	[Fact]
	public async Task TestWithEndpoint_ExpectedResponse ()
	{
		using var host = await new HostBuilder()
			.ConfigureWebHost(webBuilder =>
			{
				webBuilder
					.UseTestServer()
					.ConfigureServices(services =>
					{
						services.AddRouting();
					})
					.Configure(app =>
					{
						app.UseRouting();
						app.UseMiddleware<MyMiddleware>();
						app.UseEndpoints(endpoints =>
						{
							endpoints.MapGet("/hello", () =>
								TypedResults.Text("Hello Tests"));
						});
					});
			})
			.StartAsync();

		var client = host.GetTestClient();

		var response = await client.GetAsync("/hello");

		Assert.True(response.IsSuccessStatusCode);
		var responseBody = await response.Content.ReadAsStringAsync();
		Assert.Equal("Hello Tests", responseBody);

yaklaşımı server.SendAsynckullanılarak ek yollar da eklenebilir.

TestServer sınırlamaları

TestServer:

  • Ara yazılımı test etmek için sunucu davranışlarını çoğaltmak için oluşturuldu.
  • Tüm HttpClient davranışları çoğaltmaya çalışmaz.
  • İstemciye, sunucu üzerinde mümkün olduğunca fazla denetime ve sunucuda neler olduğuna olabildiğince fazla görünürlükle erişmeye çalışır. Örneğin, sunucu durumunu doğrudan iletmek için normalde tarafından HttpClient atılmayan özel durumlar atabilir.
  • Bazı aktarıma özgü üst bilgileri varsayılan olarak ayarlamaz çünkü bunlar genellikle ara yazılımla ilgili değildir. Daha fazla bilgi edinmek için sonraki bölüme bakın.
  • Stream üzerinden StreamContentgeçirilen konumu yoksayar. HttpClient , konumlandırma ayarlandığında bile akışın tamamını başlangıç konumundan gönderir. Daha fazla bilgi için bu GitHub konusuna bakın.

İçerik Uzunluğu ve Aktarım Kodlama üst bilgileri

TestServer, İçerik Uzunluğu veya Aktarım Kodlaması gibi aktarımla ilgili istek veya yanıt üst bilgilerini ayarlamaz. Kullanımları istemciye, senaryoya ve protokole göre değişiklik gösterdiğinden uygulamaların bu üst bilgilere bağlı olmaması gerekir. Content-Length Belirli bir senaryoyu test etmek için ve Transfer-Encoding gerekiyorsa, veya HttpContextoluşturulurken HttpRequestMessage testte belirtilebilir. Daha fazla bilgi için aşağıdaki GitHub sorunlarına bakın: