1. Install NuGet package
dotnet add package StackExchange.Redis 2. Configuration connection string
Here, I config it in appsettings.json
"ConnectionStrings": { "Redis": "localhost:6379" } 3. Configure connectiong string in Program.cs
builder.Services.AddSingleton<IConnectionMultiplexer>(sp => { var redisCon = builder.Configuration.GetConnectionString("Redis")!; var configuration = ConfigurationOptions.Parse(redisCon, true); configuration.ResolveDns = true; return ConnectionMultiplexer.Connect(configuration); }); 4. DI IConnectionMultiplexer to service
public class BasicJwtTokenValidationMiddleware { private readonly RequestDelegate _next; private readonly List<string> _authWhiteList; private readonly IConnectionMultiplexer _redis; public BasicJwtTokenValidationMiddleware(RequestDelegate next, IOptions<AuthenticationOptions> authOptions, IConnectionMultiplexer redis) { _next = next; _authWhiteList = authOptions.Value.AuthWhiteList; _redis = redis; } public Task Invoke(HttpContext context) { // ***** var redisVersion = await _redis.GetDatabase().StringGetAsync($"jwt:version:{userPublicId}"); // *** } } 5. How to mock it in unit test (use AutoFixture + Moq)
[Theory, AutoMoqData] public async Task IsValidVersionAsync_ReturnsTrue_WhenVersionMatches( [Frozen] Mock<IConnectionMultiplexer> redisMock, [Frozen] Mock<IDatabase> dbMock) { // Arrange var userId = "user-123"; var version = "3"; dbMock.Setup(db => db.StringGetAsync($"jwt:version:{userId}", It.IsAny<CommandFlags>())) .ReturnsAsync(version); redisMock.Setup(r => r.GetDatabase(It.IsAny<int>(), null)) .Returns(dbMock.Object); } Why do we mock GetDatabase with parameters even though we call it without parameters in code?
Answer: Because GetDatabase uses default parameter values in C#;
Method definition of GetDatabase:
IDatabase GetDatabase(int db = -1, object? asyncState = null); So, if we mock with our parameters like:redisMock.Setup(c => c.GetDatabase()). It won't match the actual call to GetDatabase(-1, null)
Top comments (0)