.Net Core Unit Testing With Url.Action

590 Views Asked by At

I am currently running unit tests on a controller that utilizes Url.Action to get the absolute path of two different routes. I am using Moq to set up the mock Action. The test is currently failing with the message 'Object reference not set to an instance of an object.'

[Edit - Clarifying the question]

When I debug the test, the Url shows to as a Mock<IUrlHelper> with an ActionContext property, but on the line where it calls the Url.Action, the Action property shows as null. What am I missing when setting up the Mock<IUrlHelper> that way the Url.Action doesn't come back as null?

I've checked multiple options for setting up Mock Url Actions, but nothing has seemed to work for me.

Here is the setup for the test

[Fact]
public async void SendGroup_PassesDetailsToNotificationService()
{
    UrlActionContext actualContext = null;
    var criteria = new NotificationCriteria { Section = 1, Subsection = 2 };
    userSvc.GetNotificationGroupReturnValue = new List<NotificationRecipient>
        {
            new NotificationRecipient{ SmsAuth = true } 
        };
    var actionContext = new ActionContext
        {
            ActionDescriptor = new ActionDescriptor(),
            RouteData = new RouteData(),
        };
    var urlHelper = new Mock<IUrlHelper>();
    urlHelper.SetupGet(h => h.ActionContext).Returns(actionContext);
    urlHelper.Setup(h => h.Action(It.IsAny<UrlActionContext>()))
             .Callback((UrlActionContext context) => actualContext = context);
    controller.Url = urlHelper.Object;

    var dummy = await controller.SendGroup(criteria);

    Assert.Same(criteria, notificationSvc.SendGroupNotificationDetailUsed);
}

This is the code for the controller

[HttpPost]
public async Task<IActionResult> SendGroup([FromBody]NotificationCriteria criteria)
{
    List<NotificationRecipient> recipients = (await userSvc.GetNotificationGroup(
                                              criteria.Section, criteria.Subsection)).ToList();

    if (!recipients.Any())
    {
        return BadRequest();
    }

    var uro = Url;
    var sectionUrl = Url.Action("Index", "ReportHome", new {sectionId = criteria.Section}, Request.Scheme);
    var profileUrl = Url.Action("Index", "Profile", null, Request.Scheme);
    var detail = new NotificationDetail
    {
        SectionUrl = sectionUrl,
        ProfileUrl = profileUrl,
        Recipients = recipients
    };
    try
    {
        await notificationSvc.SendGroupNotification(detail);
    }
    catch 
    {
        return StatusCode(500);
    }

    return Ok();
}
0

There are 0 best solutions below