[英]NullReference durning testing controller with NUnit and Moq
我在测试中获得了 NullReference 异常。 当我评论eventsRepository.AddEvent(eve, User.Identity.GetUserId()); 在控制器中比它通过。
我该如何解决?
控制器的方法
[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");
}
}
添加事件
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
属性未在您的测试方法中设置,因此访问时它将为空
您需要使用虚拟用户帐户设置控制器上下文。 这是一个帮助器类,您可以使用它来模拟获取用户主体所需的HttpContext
。
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;
}
}
}
在初始化目标控制器后的测试中,您需要设置控制器上下文
//...other coder
var target = new EventController(EventRepo.Object, ParticipantsRepo.Object);
target.ControllerContext = new ControllerContext {
Controller = target,
HttpContext = new MockHttpContext("fakeuser@example.com")
};
//...other coder
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.