Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.net core Url.Action mock, how to?

How to mock Url.Action during testing controller action?

I'm trying to unit test my asp.net core controller action. Logic of action has Url.Action and I need to mock it to complete test but I can't find right solution.

Thank you for your help!

UPDATE this is my method in controller that I need to test.

    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);
    }

I have problem with mocking this part:

var callbackUrl = Url.Action("Confirm", "EmailConfirmation", new { userId = user.Id, token }, HttpContext.Request.Scheme);
like image 320
Vladimir Rodchenko Avatar asked Feb 13 '17 19:02

Vladimir Rodchenko


1 Answers

Finally I found solution!

When you are mocking UrlHelper you need to mock only base method Url.Action(UrlActionContext context) because all helper methods actually use it.

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

        _controller.Url = mockUrlHelper.Object;

Also! I have problem because of null in HttpContext.Request.Scheme. You need to mock HttpContext

_controller.ControllerContext.HttpContext = new DefaultHttpContext();
like image 124
Vladimir Rodchenko Avatar answered Nov 11 '22 07:11

Vladimir Rodchenko