title: Mock User.Identity in ASP.NET Core for Unit Testing
body: <p>I am struggling to implement unit testing for action methods that incorporate <code>User.Identity.Name</code> functionality. The methods that I've come across fail because the properties that they suggest writing to throw 'read-only' errors (e.g. writing to <code>HttpContext</code> or the controller <code>User</code>)</p>
  
  <p>I have an action method:</p>
  
  <pre><code>[Authorize]
          public async Task&lt;ViewResult&gt; EditProject(int projectId)
          {
              Project project = repository.Projects.FirstOrDefault(p =&gt; p.ProjectID == projectId);
              if (project != null)
              {
              //HOW DO I MOCK USER.IDENTITY.NAME FOR THIS PORTION?
                  var user = await userManager.FindByNameAsync(User.Identity.Name); 
                  bool owned = await checkIfUserOwnsItem(project.UserID, user);
                  if (owned)
                  {
                      return View(project);
                  }
                  else
                  {
                      TempData["message"] = $"User is not authorized to view this item";
                  }
               }
              return View("Index");
          }
  </code></pre>
  
  <p>If I want to unit test this action method, how can I mock up the <code>User.Identity</code> object?</p>
  
  <pre><code>[Fact]
          public async Task Can_Edit_Project()
          {
              //Arrange
              var user = new AppUser() { UserName = "JohnDoe", Id = "1" };
              Mock&lt;IRepository&gt; mockRepo = new Mock&lt;IRepository&gt;();
              mockRepo.Setup(m =&gt; m.Projects).Returns(new Project[]
              {
                  new Project {ProjectID = 1, Name = "P1", UserID = "1"},
                  new Project {ProjectID = 2, Name = "P2", UserID = "1"},
                  new Project {ProjectID = 3, Name = "P3", UserID = "1"},
              });
              Mock&lt;ITempDataDictionary&gt; tempData = new Mock&lt;ITempDataDictionary&gt;();
              Mock&lt;UserManager&lt;AppUser&gt;&gt; userMgr = GetMockUserManager();
              //Arrange
              ProjectController controller = new ProjectController(mockRepo.Object, userMgr.Object)
              {
                  TempData = tempData.Object,
              };
  
  
             //HOW WOULD I MOCK THE USER.IDENTITY.NAME HERE?
             //The example below causes two errors:
             // 1) 'Invalid setup on a non-virtual (overridable in VB) member
             //mock =&gt; mock.HttpContext
             //and 2) HttpContext does not contain a definition for IsAuthenticated
             var mock = new Mock&lt;ControllerContext&gt;();
             mock.SetupGet(p =&gt; p.HttpContext.User.Identity.Name).Returns(user.UserName);
            mock.SetupGet(p =&gt; p.HttpContext.Request.IsAuthenticated).Returns(true);
  
              //Act
              var viewResult = await controller.EditProject(2);
              Project result = viewResult.ViewData.Model as Project;
  
              //Assert
              Assert.Equal(2, result.ProjectID);
          }
  </code></pre>
  
  <p>EDIT:
  Making some progress by adding the code below. </p>
  
  <pre><code>var claims = new List&lt;Claim&gt;()
              {
                  new Claim(ClaimTypes.Name, "John Doe"),
                  new Claim(ClaimTypes.NameIdentifier, "1"),
                  new Claim("name", "John Doe"),
              };
              var identity = new ClaimsIdentity(claims, "TestAuthType");
              var claimsPrincipal = new ClaimsPrincipal(identity);
  
              var mockPrincipal = new Mock&lt;IPrincipal&gt;();
              mockPrincipal.Setup(x =&gt; x.Identity).Returns(identity);
              mockPrincipal.Setup(x =&gt; x.IsInRole(It.IsAny&lt;string&gt;())).Returns(true);
  
              var mockHttpContext = new Mock&lt;HttpContext&gt;();
              mockHttpContext.Setup(m =&gt; m.User).Returns(claimsPrincipal);
  </code></pre>
  
  <p>The <code>User.Identity.Name</code> is set properly now, but the line below still returns a <code>user = null</code></p>
  
  <p><code>var user = await userManager.FindByNameAsync(User.Identity.Name);</code></p>
  
  <p>How can I make sure my mocked <code>UserManager</code> can return a mocked logged in user?</p>