【问题标题】:Null reference on user identity对用户身份的空引用
【发布时间】:2017-05-13 09:32:58
【问题描述】:

我是编写单元测试用例的新手。我在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( ));
}

这里我必须在ViewModel.Logs.ApplicationLogViewModel 中传递userId,我不知道该怎么做。

如何获取通过applicationLogViewModeluserId

【问题讨论】:

  • 您还应该注意,被测方法可以返回视图结果或重定向到操作结果,但单元测试正在检查 JSON 结果。这将导致 actual 变量为 null
  • null 用户的主要原因是该方法正在访问User.Identity 但控制器的User 属性未在测试方法中设置/安排。
  • @Nkosi 您好,感谢您的评论,我需要知道而不是 Json 结果,如果我通过操作结果,我应该如何编写 Assert?例如在我的控制器中,我传递值然后重定向页面。请看上面我的控制器

标签: c# unit-testing asp.net-mvc-4 moq


【解决方案1】:

一种解决方案是更改EnthiranController 并传递,例如IUserContext,如下所示:

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

然后通过构造函数将其传递给控制器​​,并使用该上下文来检索用户。

ctor EnthiranController(IUserContext userContext)

然后稍微更改单元测试以模拟所有这些接口。您也可以使用ActionResultRedirectToRouteResult 代替JsonResult,如下例所示。

[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);
}

【讨论】:

  • 您好,感谢您的评论,它工作正常,但我需要知道而不是 Json 结果,如果我通过操作结果,我应该如何编写 Assert?例如在我的控制器中,我传递值然后重定向页面。
  • @Sriram 如果您想验证重定向分支是否已执行,那么您可以验证 ActionResult 的类型是否为 RedirectToRouteResult
  • 一旦我将 Json 结果更改为操作结果,变量实际得到空引用错误。而且我还需要根据控制器数据将其重定向到另一个页面。
  • @Sriram 看看 Nkosi 的帖子。这也是您可以验证的方式,我将编辑我的答案以包含代码的和平。
  • @Lepijohnny,因为您在答案中已对其进行了更新,因此我可以删除我的。只需确保将其作为解决原始问题所需的更改之一提及即可。
猜你喜欢
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2020-03-07
  • 2022-01-21
  • 2021-04-05
相关资源
最近更新 更多