【发布时间】:2021-07-09 10:06:40
【问题描述】:
我正在尝试编写单元测试来测试给定令牌过期时的 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'.
【问题讨论】:
-
JWT 不会在一毫秒内过期,因为时间戳格式(unix 纪元时间以秒为单位)的分辨率为一秒。因此,您可能会得到 0 或 1 秒,当它为 0 时,您会得到观察到的错误。
-
@jps,感谢您提供的信息,但如何正确测试呢?
-
在使用令牌或模拟时钟之前等待。
-
在某些时候,您使用 DateTime.UtcNow 或类似的东西来初始化 Token 并为其生命周期添加 Timespans。当您控制代码中交付的时间时(不直接使用 DateTime,而是可以模拟的接口并可以返回任意日期时间),您可以控制“现在”的内容,并且可以轻松地测试与时间相关的代码。
-
google了这个例子codopia.wordpress.com/2017/04/24/…
标签: c# unit-testing asp.net-core token