Last active
August 7, 2023 21:33
-
-
Save zetroot/b26fc6ea939403538f7c0fc7edc6b85f to your computer and use it in GitHub Desktop.
Middleware lifetime tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using FluentAssertions; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.Mvc.Testing; | |
using MiddlewareApp; | |
using NUnit.Framework; | |
namespace MiddlewareAppTests; | |
public class AppFac : WebApplicationFactory<Program> | |
{ | |
private readonly string _lifetime; | |
public AppFac(string lifetime) | |
{ | |
_lifetime = lifetime; | |
} | |
protected override void ConfigureWebHost(IWebHostBuilder builder) | |
{ | |
builder.UseSetting("MIDDLEWARE_LIFETIME", _lifetime); | |
base.ConfigureWebHost(builder); | |
} | |
} | |
public class MiddlewareLifetimeTests | |
{ | |
[Test] | |
public async Task Sut_WhenMiddlewareIsTransient_AlwaysReturns1() | |
{ | |
//arrange | |
var factory = new AppFac("transient"); | |
var client = factory.CreateClient(); | |
var results = new List<int>(); | |
//act | |
for (int i = 0; i < 5; ++i) | |
{ | |
var response = await client.GetAsync("/"); | |
var contents = await response.Content.ReadAsStringAsync(); | |
results.Add(int.Parse(contents)); | |
} | |
// assert | |
results.Should().AllSatisfy(x => x.Should().Be(1)); | |
} | |
[Test] | |
public async Task Sut_WhenMiddlewareIsScoped_AlwaysReturns1() | |
{ | |
//arrange | |
var factory = new AppFac("scoped"); | |
var client = factory.CreateClient(); | |
var results = new List<int>(); | |
//act | |
for (int i = 0; i < 5; ++i) | |
{ | |
var response = await client.GetAsync("/"); | |
var contents = await response.Content.ReadAsStringAsync(); | |
results.Add(int.Parse(contents)); | |
} | |
// assert | |
results.Should().AllSatisfy(x => x.Should().Be(1)); | |
} | |
[Test] | |
public async Task Sut_WhenMiddlewareIsSingleton_ReturnsDifferentValues() | |
{ | |
//arrange | |
var factory = new AppFac("singleton"); | |
var client = factory.CreateClient(); | |
var results = new List<int>(); | |
//act | |
for (int i = 0; i < 5; ++i) | |
{ | |
var response = await client.GetAsync("/"); | |
var contents = await response.Content.ReadAsStringAsync(); | |
results.Add(int.Parse(contents)); | |
} | |
// assert | |
results.Should().SatisfyRespectively( | |
x => x.Should().Be(1), | |
x => x.Should().Be(2), | |
x => x.Should().Be(3), | |
x => x.Should().Be(4), | |
x => x.Should().Be(5) | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace MiddlewareApp; | |
public class Program | |
{ | |
public static async Task Main(string[] args) | |
{ | |
var builder = WebApplication.CreateBuilder(args); | |
var lifetime = builder.Configuration.GetValue<string>("MIDDLEWARE_LIFETIME") switch | |
{ | |
"singleton" => ServiceLifetime.Singleton, | |
"scoped" => ServiceLifetime.Scoped, | |
"transient" => ServiceLifetime.Transient, | |
_ => throw new InvalidOperationException("Service lifetime unrecognized") | |
}; | |
builder.Services.Add(new(typeof(CountMiddleware), typeof(CountMiddleware), lifetime)); | |
var app = builder.Build(); | |
app.UseMiddleware<CountMiddleware>(); | |
app.MapGet("/", () => "It's wednesday, my dudes"); | |
await app.RunAsync(); | |
} | |
} | |
public class CountMiddleware : IMiddleware | |
{ | |
private int _counter = 0; | |
public async Task InvokeAsync(HttpContext context, RequestDelegate next) | |
{ | |
++_counter; | |
context.Response.StatusCode = 200; | |
await using var sw = new StreamWriter(context.Response.Body); | |
await sw.WriteLineAsync(_counter.ToString()); | |
await sw.FlushAsync(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Простой тест жизненного цикла миддлвари.
Transient
иScoped
явно не сохраняют свое состояние - инстанциируются каждый раз на запрос.Siтgleton
- наоборот, сохраняет и увеличивает значение счетчика на каждом запросе, то есть она инстанциируется один раз за время жизни программы.