问题描述
我在测试中获得了NullReference异常.当我评论控制器中的 eventsRepository.AddEvent(eve,User.Identity.GetUserId()); 时.
I obtain a NullReference exception in my test. When I comment eventsRepository.AddEvent(eve, User.Identity.GetUserId()); in controller than it goes through.
我该如何解决?
控制器方法
[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);
测试方法
[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"]);
}
推荐答案
您正在访问User.Identity.GetUserId()
,但是未在测试方法中设置控制器的User
属性,因此访问时该属性将为空
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
您将需要使用虚拟用户帐户设置控制器上下文.这是一个帮助器类,您可以用来模拟获取用户主体所需的HttpContext
.
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
这篇关于具有NUnit和Moq的NullReference延音测试控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!