.net core Url.Action mock,怎么样?

时间:2017-02-13 19:31:35

标签: unit-testing asp.net-core-mvc moq

如何在测试控制器操作期间模拟Url.Action?

我试图对我的asp.net核心控制器操作进行单元测试。 行动逻辑有Url.Action,我需要嘲笑它才能完成测试,但我无法找到正确的解决方案。

感谢您的帮助!

更新 这是我需要测试的控制器中的方法。

    public async Task<IActionResult> Index(EmailConfirmationViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _userManager.FindByNameAsync(model.Email);

            if (user == null) return RedirectToAction("UserNotFound");
            if (await _userManager.IsEmailConfirmedAsync(user)) return RedirectToAction("IsAlreadyConfirmed");

            var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            var callbackUrl = Url.Action("Confirm", "EmailConfirmation", new { userId = user.Id, token }, HttpContext.Request.Scheme);

            await _emailService.SendEmailConfirmationTokenAsync(user, callbackUrl);

            return RedirectToAction("EmailSent");
        }

        return View(model);
    }

我有嘲笑这部分的问题:

var callbackUrl = Url.Action("Confirm", "EmailConfirmation", new { userId = user.Id, token }, HttpContext.Request.Scheme);

2 个答案:

答案 0 :(得分:24)

最后我找到了解决方案!

当您模拟UrlHelper时,您只需要模拟基本方法 Url.Action(UrlActionContext context),因为所有帮助方法实际上都使用它。

        var mockUrlHelper = new Mock<IUrlHelper>(MockBehavior.Strict);
        mockUrlHelper
            .Setup(
                x => x.Action(
                    It.IsAny<UrlActionContext>()
                )
            )
            .Returns("callbackUrl")
            .Verifiable();

        _controller.Url = mockUrlHelper.Object;

另外!因为HttpContext.Request.Scheme中的null,我有问题。你需要模拟HttpContext

_controller.ControllerContext.HttpContext = new DefaultHttpContext();

答案 1 :(得分:1)

我添加了

var urlHelperMock = new Mock<IUrlHelper>();
urlHelperMock
  .Setup(x => x.Action(It.IsAny<UrlActionContext>()))
  .Returns((UrlActionContext uac) =>
    $"{uac.Controller}/{uac.Action}#{uac.Fragment}?"
    + string.Join("&", new RouteValueDictionary(uac.Values).Select(p => p.Key + "=" + p.Value)));
controller.Url = urlHelperMock.Object;

到我的通用控制器设置。这有点粗糙,但意味着我可以测试任何生成链接的控制器逻辑。