问题
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