首页 > 解决方案 > 令牌必须过期时如何对场景进行单元测试?

问题描述

我正在尝试编写单元测试来测试给定令牌过期时的 AuthenticationService 响应。我现在这样做的方式 - 我将到期日期设置为 1 毫秒,但这非常不稳定。有更好的方法吗?

这是我的单元测试方法的代码:

/// <summary>
/// Tests service response when refreshing tokens with non-expired refresh token.
/// </summary>
[Fact]
public async void AuthService_UserRefreshesTokens_AuthenticationResponseWithRefreshTokenHasExpiredError()
{
    // Arrange
    _fixture.JwtCfg.TokenLifetime = new TimeSpan(0, 0, 0, 0, 1);
    _fixture.RefreshTokenCfg.TokenLifetime = new TimeSpan(0, 0, 0, 0, 1);
    var authResponse = await _fixture.TokenSrvc.GenerateTokenPairForUserAsync(_fixture.Users.First());
    var request = new RefreshTokenRequest
    {
        Token = authResponse.Token,
        RefreshToken = authResponse.RefreshToken
    };
    ((List<RefreshToken>)_fixture.RefreshTokens).Add(new RefreshToken { Token = request.RefreshToken });

    // Act
    var response = await _fixture.AuthSrvc.RefreshTokenAsync(request);

    // Assert
    response.Success.Should().BeFalse();
    response.Errors.Should().ContainSingle();
    response.Errors.ToList()[0].Should().Be("Refresh token has expired, user needs to re-login.");
}

使用这种方法,我得到下一个错误:

System.ArgumentException: IDX12401: Expires: 'System.DateTime' must be after NotBefore: 'System.DateTime'.

标签: c#unit-testingasp.net-coretoken

解决方案


正如@Ralf 提到的,最简单的方法是延迟 1 秒。

/// <summary>
/// Tests service response when refreshing tokens with non-expired refresh token.
/// </summary>
[Fact]
public async void AuthService_UserRefreshesTokens_AuthenticationResponseWithRefreshTokenHasExpiredError()
{
    // Arrange
    _fixture.JwtCfg.TokenLifetime = TimeSpan.FromSeconds(1);
    _fixture.RefreshTokenCfg.TokenLifetime = TimeSpan.FromSeconds(1);
    var authResponse = await _fixture.TokenSrvc.GenerateTokenPairForUserAsync(_fixture.Users.First());
    var request = new RefreshTokenRequest
    {
        Token = authResponse.Token,
        RefreshToken = authResponse.RefreshToken
    };
    ((List<RefreshToken>)_fixture.RefreshTokens).Add(new RefreshToken { Token = request.RefreshToken });

    // now wait a little
    await Task.Delay(1001);

    // Act
    var response = await _fixture.AuthSrvc.RefreshTokenAsync(request);

    // Assert
    response.Success.Should().BeFalse();
    response.Errors.Should().ContainSingle();
    response.Errors.ToList()[0].Should().Be("Refresh token has expired, user needs to re-login.");
}

推荐阅读