Search code examples
.net.net-coreasp.net-core-mvc

IUrlHelper seems null when instantiate controller from Test case


Inside a controller action i have

       public async Task Delete()
        {
           var redirectUrl = Url.Action(
                                action: "Test",
                                controller: "TestController",
                                values: new { area = "TestArea" },
                                protocol: Request.Scheme
                            );
        }

It works normal when my web app runs, but If call the action from a Unit test case:

    var controller = new TController();
    await controller.Delete();

Url is null


Solution

  • If you want to mock the url.action, you need firstly mock the iurlhelper, then let the iurlhelper to help url action to generate the result.

    More details, you could refer to below codes:

    // Arrange
    var logger = new Mock<ILogger<HomeController>>();
    
    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)));
    
    var httpContext = new DefaultHttpContext();
    httpContext.Request.Scheme = "http";
    httpContext.Request.Host = new HostString("localhost");
    
    var controllerContext = new ControllerContext
    {
        HttpContext = httpContext,
    
    };
    
    var controller = new HomeController(logger.Object)
    {
        Url = urlHelperMock.Object,
        ControllerContext = controllerContext, // Assign the ControllerContext with the mock HttpContext
    };
    
    // Now, you can call your action method
    var result =   controller.Delete();
    

    Result:

    enter image description here