2016-12-29 37 views
1

我是編寫單元測試用例的新手。我在User.Identity上遇到錯誤。我看到嘲笑是解決這個問題的方法,我嘗試了一些不適合我的案例。我已經加入我的代碼關於用戶身份的空引用

我的控制器

public ActionResult CreateStage (EnthiranStageViewModel enthiranStage) 
{ 
    if (ModelState.IsValid) 
    { 
     Stage stage = enthiran.Insert_Stage(enthiranStage); 
     //logging Stage Creation 
     util.ApplicationLog(new ViewModel.Logs.ApplicationLogViewModel 
     { 
     GameCategorys = GameCategory.Enthiran, 
     Event = Events.EnthiranStageCreation, 
     SessionAttemptId = null, 
     UserId = User.Identity.GetUserId<int>(), 
     OptionalParameter1 = enthiranStage.GameId, 
     OptionalParameter2 = stage.Id, 
     Description = "Enthiran stage created" 
     }); 
     return RedirectToAction("Stages", new 
     { 
      id = stage.GameId 
     }); 
    } 
    return View(); 
} 

以下是我測試的情況下

[TestMethod()] 
public void createStage () 
{ 
    EnthiranStageViewModel enthiranStage = new EnthiranStageViewModel 
    { 
     StageType=0, 
     TriggerBeginType = Akton.Areas.Challenge.Models.TriggerType.Manual, 
     TriggerEndType= Akton.Areas.Challenge.Models.TriggerType.Manual, 
     TimeLimit = new TimeSpan(9, 6, 13), 
     TriggerBeginTime= new DateTime(2016, 09, 3, 9, 6, 13), 
     TriggerEndTime= new DateTime(2016, 09, 3, 9, 6, 13), 
     StartValueType= Akton.Areas.Challenge.Models.StartValueType.Global, 
     StageDate= new DateTime(2016, 09, 3, 9, 6, 13), 
     Proforma=25, 
     GameId=19, 
     CreatedTime=new DateTime(2016, 09, 3, 9, 6, 13), 
     UpdatedTime= new DateTime(2016, 09, 3, 9, 6, 13), 
     StageName="Test", 

    }; 
    EnthiranController controller = new EnthiranController(); 
    JsonResult actual = controller.CreateStage(enthiranStage) as JsonResult; 
    var result = actual.Data; 
    Assert.AreEqual("{ success = True }", result.ToString()); 
} 

在這裏,我必須通過userIdViewModel.Logs.ApplicationLogViewModel,我不知道該怎麼做。

我該如何得到applicationLogViewModeluserId

+0

檢查https://stackoverflow.com/questions/40230776/how-to-mock-httpcontext-user/40234602#40234602 – Nkosi

+0

檢查http://stackoverflow.com/a/39453132/5233410 – Nkosi

+0

你應該還要注意被測方法可以返回一個視圖結果或者重定向到操作結果,但是單元測試正在檢查JSON結果。這將導致'actual'變量爲'null' – Nkosi

回答

2

一種解決方案是改變EnthiranController,並通過,例如,IUserContext,這樣的事情:

public interface IUserContext 
{ 
    public IPrincipal User {get;} 
} 

然後傳遞通過構造到所述控制器,並使用該上下文來檢索用戶。

ctor EnthiranController(IUserContext userContext) 

然後稍微改變單元測試來模擬所有這些接口。而不是JsonResult,您可以使用ActionResultRedirectToRouteResult,如下例所示。

[TestMethod()] 
public void createStage () 
{ 
    //arrange 
    EnthiranStageViewModel enthiranStage = new EnthiranStageViewModel 
    { 
     StageType=0, 
     TriggerBeginType = Akton.Areas.Challenge.Models.TriggerType.Manual, 
     TriggerEndType= Akton.Areas.Challenge.Models.TriggerType.Manual, 
     TimeLimit = new TimeSpan(9, 6, 13), 
     TriggerBeginTime= new DateTime(2016, 09, 3, 9, 6, 13), 
     TriggerEndTime= new DateTime(2016, 09, 3, 9, 6, 13), 
     StartValueType= Akton.Areas.Challenge.Models.StartValueType.Global, 
     StageDate= new DateTime(2016, 09, 3, 9, 6, 13), 
     Proforma=25, 
     GameId=19, 
     CreatedTime=new DateTime(2016, 09, 3, 9, 6, 13), 
     UpdatedTime= new DateTime(2016, 09, 3, 9, 6, 13), 
     StageName="Test"  
    }; 

    Mock<IPrincipal> mockPrincipal = new Mock<IPrincipal>(); 
    //TODO: setup mockPrincipal 
    Mock<IUserContext> mockUserContext = new Mock<IUserContext>(); 
    mockUserContext.Setup(p => p.User).Returns(mockPrincipal.Object); 

    EnthiranController controller = new EnthiranController(mockUserContext.Object); 

    //act 
    var actual = controller.CreateStage(enthiranStage) as RedirectToRouteResult; 

    //assert 
    Assert.IsNotNull(actual); 
} 
+0

你好,感謝評論,它的工作正常,但我需要知道,而不是Json結果,如果我傳遞行動結果,我應該如何寫Assert?例如在我的控制器中,我傳遞的值然後重定向頁面。 – Sriram

+0

@Sriram如果你想驗證重定向分支是否被執行,那麼你可以驗證'ActionResult'的類型是'RedirectToRouteResult'。 – Johnny

+0

一旦我將Json結果更改爲操作結果,變量實際得到空引用錯誤。還需要根據控制器數據將其重定向到另一個頁面。 – Sriram