0

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();
}
  • What overload are you suggesting I use? – ShaggyMunky May 10 '20 at 05:00
  • 1
    Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Pavel Anikhouski May 10 '20 at 07:41
  • Excuse me, I thought of the .Net framework urlhelper, which has overloads. This one does not. – Jesse de Wit May 10 '20 at 13:55
  • @PavelAnikhouski My question isn't so much as to what the error means, I am familiar with the message. I'm asking what am I missing in the Mock that is causing the `Url.Action` to come back as a null reference. – ShaggyMunky May 11 '20 at 20:19

0 Answers0