1

Can someone please help to explain why this is failing? I think I might tracked it down to having something to do with User.Identity.Name. It fails at "Act" and I get a System.NullReferenceException. However another method in the same controller does work.

WORKING TEST

[TestMethod] public void Home_Index_Returns_ActionResult() { //Arrange var mockRepository1 = new Mock<IEditDataRepository>(); var mockRepository2 = new Mock<IIdentityRepository>(); mockRepository1 .Setup(x => x.Edit(It.IsAny<UTCFormViewModel>(), It.IsAny<string>())); HomeController controller = new HomeController(mockRepository1.Object, mockRepository2.Object); //Act ActionResult result = controller.Index(); //Assert Assert.IsInstanceOfType(result, typeof(ActionResult)); } 

NOT WORKING TEST (on a different method)

[TestMethod] public void Edit_Method_Test() { //Arrange var mockRepository1 = new Mock<IEditDataRepository>(); var mockRepository2 = new Mock<IIdentityRepository>(); mockRepository1 .Setup(x => x.Edit(It.IsAny<UTCFormViewModel>(), It.IsAny<string>())); HomeController controller = new HomeController(mockRepository1.Object, mockRepository2.Object); //Act (Fails Here) controller.Edit(It.IsAny<UTCFormViewModel>()); //Assert mockRepository1.VerifyAll(); mockRepository2.VerifyAll(); } 

CONTROLLER

namespace UTC.Controllers { [Authorize] public class HomeController : Controller { private IEditDataRepository _editDataRepository; private IIdentityRepository _identityRepository; public HomeController(IEditDataRepository editDataRepository, IIdentityRepository identityRepository ) { _editDataRepository = editDataRepository; _identityRepository = identityRepository; } public ActionResult Index() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "Field1, Field2")] UTCFormViewModel model) { if (ModelState.IsValid) { string fullWindowsUser = User.Identity.Name; string windowsUser = _identityRepository.GetWindowsUser(fullWindowsUser); _editDataRepository.Edit(model, windowsUser); return new HttpStatusCodeResult(HttpStatusCode.OK); } else { throw new HttpException(400, "ModelState Invalid"); } } } } 

REPOSITORY

namespace UTC.Repositories { public class IdentityRepository : IIdentityRepository { public string GetWindowsUser(string fullWindowsUser) { //Strip off the domain and lower text var windowsUser = fullWindowsUser.ToString().ToLower().Split('\\')[1]; return windowsUser; } } } 

REPOSITORY

namespace UTC.Repositories { public class EditDataRepository : IEditDataRepository { private UTCEntities db = new UTCEntities(); public void Edit(UTCFormViewModel model, string windowsUser) { db.ustp_UTCUpdate(windowsUser, model.Field1, model.Field2) ); } } 
5
  • What's the stack trace say? Commented Oct 4, 2016 at 23:06
  • I'm just getting this message System.NullReferenceException: Object reference not set to an instance of an object. Commented Oct 4, 2016 at 23:09
  • That's the "message" of the exception. The exception also has a "stacktrace", which will tell you the exact line where it occurred in the controller. Debug the test to inspect it. Commented Oct 4, 2016 at 23:19
  • You would be correct about User.Identity.Name. you need to set a fake user for the controller which is null by default unless otherwise setup in the controller context Commented Oct 4, 2016 at 23:20
  • You need to mock the user. Refer the answers here and here Commented Oct 4, 2016 at 23:20

1 Answer 1

1

You are accessing User.Identity.Name but the User property of the controller was not setup in your test method hence it will be null when accessed

you will need to set the controller context with a dummy user account. Here is a helper class you can use to mock the HttpContext needed to get the user principal.

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

in your test after initializing the target controller you would need to set the controller context

//...other code removed for brevity var controller = new HomeController(mockRepository1.Object, mockRepository2.Object); controller.ControllerContext = new ControllerContext { Controller = controller, HttpContext = new MockHttpContext("[email protected]") }; //...other code removed for brevity 
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot. I'll give a shot and let you know how it goes. One question though, where would you place that helper class?
In the test project
Works great! Outstanding! Thank You.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.