NullReference durning testing controller with NUnit and Moq

泄露秘密 提交于 2019-12-24 07:35:13

问题


I obtain a NullReference exception in my test. When I comment eventsRepository.AddEvent(eve, User.Identity.GetUserId()); in controller than it goes through.

How Can I fix it ?

Controller's Method

[ValidateAntiForgeryToken]
[HttpPost]
[Authorize]
public ActionResult CreateEvent(Event eve)
{
    if (eve.DateOfBegining < DateTime.Now)
    {
        ModelState.AddModelError("DateOfBegining", "");
    }

    if (eve.MaxQuantityOfPlayers < eve.MinCount)
    {
        ModelState.AddModelError("MinCount", "");
    }

    if (eve.ConflictSides.Count < 2 || eve.ConflictSides.Count > 10)
    {
        ModelState.AddModelError("ConflictSides", "");
    }

    if (!ModelState.IsValid)
    {
        return View("CreateEvent", eve);
    }
    else
    {
        eventsRepository.AddEvent(eve, User.Identity.GetUserId());
        return RedirectToAction("EventsList");
    }
}

AddEvent

void AddEvent(Event ev, string userId);

Test's method

[TestMethod]
public void CreateEvent_AddEvent_returns_EventsList()
{
    // arrange
    var EventRepo = new Mock<IEventRepository>();
    var ParticipantsRepo = new Mock<IParticipants>();

    DateTime dt = new DateTime(2200, 1, 23);
    Event eve = new Event() 
    {
        ConflictSides = new List<ConflictSide>() { 
                                                new ConflictSide{ Name ="niebiescy"},
                                                new ConflictSide{ Name ="czerwoni"},
                                                new ConflictSide{ Name ="fioletowi"},
                                                },
        DateOfBegining = dt,
        Description = "bardzo dlugi opid na potrzeby testu",
        EventCreator= "userId",
        EventName = "najlepsza",
        FpsLimitInBuildings=300,
        FpsLimitOnOpenField=500,
        Hicap = new MagazineTyp(){ifAllow = true, ifOnlySemi = false},
        MidCap = new MagazineTyp(){ifAllow = true, ifOnlySemi = false},
        LowCap = new MagazineTyp(){ifAllow = true, ifOnlySemi = false},
        RealCap = new MagazineTyp(){ifAllow = true, ifOnlySemi = false},
        MaxQuantityOfPlayers = 50,
        MinCount = 10           
    };

    var target = new EventController(EventRepo.Object, ParticipantsRepo.Object);

    // act

    RedirectToRouteResult result = target.CreateEvent(eve) as RedirectToRouteResult;

    // assert

    // EventRepo.Verify(a => a.AddEvent(It.IsAny<Event>(), It.IsAny<string>()), Times.Once());

    Assert.AreEqual("EventsList", result.RouteValues["action"]);
}

回答1:


You are accessing User.Identity.GetUserId() but the User property of the controller was not setup in your test method hence it will be null when accessed

you will need to set the controller context with a dummy user account. Here is a helper class you can use to mock the HttpContext needed to get the user principal.

private class MockHttpContext : HttpContextBase {
    private readonly IPrincipal user;

    public MockHttpContext(string username, string[] roles = null) {
        var identity = new GenericIdentity(username);
        var principal = new GenericPrincipal(identity, roles ?? new string[] { });
        user = principal;
    }

    public override IPrincipal User {
        get {
            return user;
        }
        set {
            base.User = value;
        }
    }
}

in your test after initializing the target controller you would need to set the controller context

//...other coder

var target = new EventController(EventRepo.Object, ParticipantsRepo.Object);
target.ControllerContext = new ControllerContext {
    Controller = target,
    HttpContext = new MockHttpContext("fakeuser@example.com")
};

//...other coder


来源:https://stackoverflow.com/questions/39452589/nullreference-durning-testing-controller-with-nunit-and-moq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!