Sriram
Sriram

Reputation: 59

Null reference on user identity

I am new to writing a unit test case. I am getting error on User.Identity. I saw mocking is the resolution for that and I tried which is not working in my case. I have added my code

My Controller

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

and below is my test case

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

Here I have to pass the userId in the ViewModel.Logs.ApplicationLogViewModel, I have no idea how to do that.

How do I get the userId which is passing through applicationLogViewModel?

Upvotes: 1

Views: 252

Answers (1)

Johnny
Johnny

Reputation: 9519

One solution is to change EnthiranController and pass, for example, IUserContext, something like this:

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

then pass that through constructor to the controller, and use that context to retrieve the user.

ctor EnthiranController(IUserContext userContext)

Then slightly change unit test to mock all these interfaces. Also instead of JsonResult you can use ActionResult or RedirectToRouteResult as it is shown in following example.

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

Upvotes: 2

Related Questions