模拟TokenProviders在身份框架中验证异步

时间:2016-07-27 09:55:12

标签: c# unit-testing mocking

我的代码中调用了来自UserManager的VerifyTwoFactorTokenAsync:

    public async Task<IdentityResult> ConfirmEmailconfirmationAsync(string token, Account user)
    {
        RegisterTwoFactorProvider(TokenType.Confirmation.ToString(), new TotpSecurityStampBasedTokenProvider<Account, int>());

        if (!await VerifyTwoFactorTokenAsync(user.Id, TokenType.Confirmation.ToString(), token))
        {
            return IdentityResult.Failed("Invalid code.");
        }

        return await ConfirmEmailAsync(user.Id, await GenerateEmailConfirmationTokenAsync(user.Id));
    }

我正在尝试模拟返回的内容,因为我无法轻易地模拟UserManager类,我正在尝试模拟此调用中使用的任何内容。

到目前为止,这是我的单元测试中相关的部分:

    [Fact]
    public async Task ItShouldReturnOk()
    {
        Account = new Account { Id = 1, UserName = "username@email.com", Email = "username@email.com" };

        UserStore.Setup(x => x.FindByIdAsync(1)).ReturnsAsync(Account);
        TokenProvider.Setup(x => x.ValidateAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<UserManager<Account, int>>(), It.IsAny<CmsAccount>())).ReturnsAsync(true);
        IHttpActionResult result = await AccountController.ConfirmEmail(Model);

        Assert.IsType<OkResult>(result);
    }

UserStore和TokenProvider都被模拟了。我原本以为这些会覆盖我,但是看一下身份框架中的源代码,我看到我的问题出现在哪里。在VerifyTwoFactorTokenAsync内部,我看到正在进行此调用:

var result = await _tokenProviders[tokenProvider].ValidateAsync("TwoFactor", token, this, user);

似乎没有使用我可以模拟的tokenProvider,除非我错过了什么。任何人都有关于如何模拟这个的想法吗?

1 个答案:

答案 0 :(得分:0)

就个人而言,我不会让我的代码难以维护,只是为了添加单元测试。添加Intefaces,依赖注入和适配器会使代码难以阅读和维护。

我建议使用一个shim / fake库,就像Visual Studio一样。这将允许您添加测试代码,而不会使您的代码难以阅读。

这样做的好处就是无需为测试包装datetime.now函数。

当任何代码调用datetime.now时,您只需注册要触发的函数。

更清洁