2016-09-12 2 views
1

Я получаю исключение NullReference в своем тесте. Когда я комментирую eventsRepository.AddEvent (eve, User.Identity.GetUserId()); в контроллере, чем он проходит.NullReference durning controller controller с NUnit и Moq

Как это исправить?

Метод контроллера

[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"]); 
} 
+0

Вы обращаетесь к 'User.Identity.GetUserId()', но свойство пользователя контроллера не был установлен в вашем методе тестирования. – Nkosi

+0

Heres другой способ издеваться над ним с поддельным http://stackoverflow.com/a/39898952/2672291 – Haohmaru

ответ

1

Вы доступ ing 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("[email protected]") 
}; 

//...other coder 
+0

Большое спасибо. Это было полезно :) – pred

Смежные вопросы