Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用户标识上的空引用_C#_Unit Testing_Asp.net Mvc 4_Moq - Fatal编程技术网

C# 用户标识上的空引用

C# 用户标识上的空引用,c#,unit-testing,asp.net-mvc-4,moq,C#,Unit Testing,Asp.net Mvc 4,Moq,我不熟悉编写单元测试用例。我在User.Identity上遇到错误。我看到嘲弄是解决这个问题的方法,我试过了,但在我的情况下不起作用。我已经添加了我的代码 我的控制器 public ActionResult CreateStage ( EnthiranStageViewModel enthiranStage ) { if ( ModelState.IsValid ) { Stage stage = enthiran.Insert_Stage(enthiranSta

我不熟悉编写单元测试用例。我在
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( );
}
这里我必须在
ViewModel.Logs.ApplicationLogViewModel
中传递
userId
,我不知道该怎么做


如何获取正在通过
applicationLogViewModel
传递的
userId

一种解决方案是更改
EnthiranController
并传递,例如,
IUserContext
,类似这样的内容:

public interface IUserContext
{
    public IPrincipal User {get;}
}
然后通过构造函数将其传递给控制器,并使用该上下文检索用户

ctor EnthiranController(IUserContext userContext)
然后稍微更改单元测试以模拟所有这些接口。也可以使用
ActionResult
RedirectToRouteResult
来代替
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);
}
[TestMethod()]
公共阶段()
{
//安排
EnthiranStageViewModel enthiranStage=新的EnthiranStageViewModel
{
StageType=0,
TriggerBeginType=Akton.Areas.Challenge.Models.TriggerType.Manual,
TriggerEndType=Akton.Areas.Challenge.Models.TriggerType.Manual,
TimeLimit=新的时间跨度(9,6,13),
TriggerBeginTime=新日期时间(2016、09、3、9、6、13),
TriggerEndTime=新的日期时间(2016,09,3,9,6,13),
StartValueType=Akton.Areas.Challenge.Models.StartValueType.Global,
StageDate=新日期时间(2016年9月3日9日6日13日),
形式=25,
配子体=19,
CreatedTime=新的日期时间(2016、09、3、9、6、13),
UpdateTime=新的日期时间(2016,09,3,9,6,13),
StageName=“测试”
};
Mock mockPrincipal=new Mock();
//TODO:安装程序
Mock mockUserContext=new Mock();
Setup(p=>p.User).Returns(mockPrincipal.Object);
EnthiranController控制器=新的EnthiranController(mockUserContext.Object);
//表演
var actual=controller.CreateStage(enthiranStage)作为RedirectToRouteResult;
//断言
Assert.IsNotNull(实际值);
}

Check检查您还应该注意,被测试的方法可以返回视图结果或重定向到操作结果,但单元测试正在检查JSON结果。这将导致
actual
变量为
null
空用户的主要原因是该方法正在访问
user.Identity
,但测试方法中未设置/安排控制器的
user
属性。@Nkosi您好,感谢您的评论,我需要知道的不是Json结果,如果我传递了操作结果,我应该如何编写断言?例如,在我的控制器中,我传递值,然后重定向页面。请看上面我的controllerHello,谢谢你的评论,它工作得很好,但我需要知道的不是Json结果,而是如果我传递操作结果,我应该如何编写断言?例如,在我的控制器中,我正在传递值,然后重定向页面。@Sriram如果要验证是否执行了重定向分支,则可以验证
ActionResult
的类型是否为
RedirectToRouteResult
。一旦我将Json结果更改为action result,变量actual getting null reference error。我还需要根据控制器数据将其重定向到另一个页面。@Sriram请看Nkosi的帖子。这也是您可以验证的方式,我将编辑我的答案以包含代码的和平。@Lepijohnny当您在答案中更新它时,我可以删除我的答案。只需确保将其作为解决原始问题所需的更改之一。
[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);
}