1

I am trying to write a unit test for my existing MVC Web Application. In that I am facing some problem like User Identity and Services calling.

My Base Controller:

public class BaseController : Controller { public AppUser CurrentUser { get { return new AppUser(this.User as ClaimsPrincipal); } } } 

Controller

public class NewsController : BaseController { private readonly iNewsService _newsService; private readonly IMapper _mapper; public NewsController(iNewsService newsService, IMapper mapper) { _newsService = newsService; _mapper = mapper; } public ActionResult List(int CompanyID == 0) { var data = _newsService.List(CompanyID, CurrentUser.CompanyType); return View(); } } 

Testing Code:

[TestClass] public class NewsControllerTest { [TestMethod] public void NewsList() { var mockNewsService = new Mock<iNewsService>(); var mockMapper = new Mock<IMapper>(); IList<Claim> claimCollection = new List<Claim> { new Claim("UserName", "admin"), new Claim("CompanyType", "true"), }; var identityMock = new Mock<ClaimsIdentity>(); identityMock.Setup(x => x.Claims).Returns(claimCollection); var cp = new Mock<ClaimsPrincipal>(); cp.Setup(m => m.HasClaim(It.IsAny<string>(), It.IsAny<string>())).Returns(true); cp.Setup(m => m.Identity).Returns(identityMock.Object); var contextMock = new Mock<HttpContextBase>(); contextMock.Setup(ctx => ctx.User).Returns(cp.Object); var controllerContextMock = new Mock<ControllerContext>(); controllerContextMock.Setup(con => con.HttpContext).Returns(contextMock.Object); controllerContextMock.Setup(con => con.HttpContext.User).Returns(cp.Object); NewsController controller = new NewsController(mockNewsService.Object, mockMapper.Object); controller.ControllerContext = controllerContextMock.Object; // Act ViewResult result = controller.List(1) as ViewResult; // Assert Assert.IsNotNull(result); } } 

AppUser Class:

public class AppUser : ClaimsPrincipal { public AppUser(ClaimsPrincipal principal) : base(principal) { } public string Name { get { return this.FindFirst("UserName").Value; } } public string CompanyType { get { return this.FindFirst("CompanyType").Value; } } } 

INewsServices :

public interface iNewsService { IEnumerable<Model.News> List(string companyType, string CompanyID); } 

Note : INewsServices is separate library

This is my actual code but its not working always my CurrentUser is null value. I am not able to assign the value in CurrentUser in parent Controller and some time my news services is also not calling the List method.

1
  • See the base controller there i have declared CurrentUser. While running the above Code CurrentUser is showing as null value ('CurrentUser.CompanyType' threw an exception type as 'System.NullReferanceException') Commented May 1, 2017 at 13:52

1 Answer 1

2

How you mock the ClaimsPrincipals is causing the FindFirst to return null and when you call Value on that it gets NRE. No need to mock the claims principals just create new instances for the test.

[TestClass] public class NewsControllerTest { [TestMethod] public void _NewsList() { //Arrange var companyId = 1; var companyType = "someType"; var claims = new List<Claim> { new Claim("UserName", "admin"), new Claim("CompanyType", companyType), }; var principal = new ClaimsPrincipal(new ClaimsIdentity(claims)); var contextMock = new Mock<HttpContextBase>(); contextMock.Setup(_ => _.User).Returns(principal); var fakeNews = new List<News>() { new News(), new News() }; var mockNewsService = new Mock<INewsService>(); mockNewsService .Setup(_ => _.List(It.IsAny<string>(), It.IsAny<string>()) .Returns(fakeNews); var controller = new NewsController(mockNewsService.Object, Mock.Of<IMapper>()); controller.ControllerContext = new ControllerContext(contextMock.Object, new RouteData(), controller); // Act ViewResult result = controller.List(companyId) as ViewResult; // Assert Assert.IsNotNull(result); mockNewsService.Verify(_ => _.List(It.IsAny<string>(), It.IsAny<string>()), Times.AtLeastOnce); } } 

You should also consider updating AppUser to avoid the NRE

public class AppUser : ClaimsPrincipal { public AppUser(ClaimsPrincipal principal) : base(principal) { } public string Name { get { return this.FindFirst("UserName")?.Value; } } public string CompanyType { get { return this.FindFirst("CompanyType")?.Value; } } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.