2016-09-12 25 views
1

私のテストではNullReference例外が発生します。私がコメントするときeventsRepository.AddEvent(eve、User.Identity.GetUserId());コントローラー内のが通過します。NUnitとMoqを使用したNullReferenceテスト制御コントローラ

どうすれば修正できますか?

コントローラのメソッド

[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

を設定する必要がありますターゲットコントローラを初期化した後)'が、コントローラのユーザー・プロパティあなたのテスト方法で設定されていませんでした。 – Nkosi

+0

fakeiteasyで他の方法を模倣することを望んでいるhttp://stackoverflow.com/a/39898952/2672291 – Haohmaru

答えて

1

あなたがアクセスしていますUser.Identity.GetUserId()コントローラのUserプロパティがテストメソッドに設定されていなかったため、アクセス時にnullになります。

ダミーのユーザーアカウントでコントローラのコンテキストを設定する必要があります。ここでは、ユーザープリンシパルを取得するために必要な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; 
     } 
    } 
} 

あなたは( `User.Identity.GetUserIdにアクセスしているコントローラコンテキスト

//...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

関連する問題