How to add claims in a mock ClaimsPrincipal

后端 未结 2 443
悲哀的现实
悲哀的现实 2020-12-15 02:50

I am trying to unit test my controller code which gets the information from the ClaimsPrincipal.Current. In the controller code I

public class HomeControlle         


        
相关标签:
2条回答
  • 2020-12-15 03:26

    You don't need to mock ClaimsPrincipal it has no outside dependencies and you can created it un-mocked:

    var claims = new List<Claim>() 
    { 
        new Claim(ClaimTypes.Name, "username"),
        new Claim(ClaimTypes.NameIdentifier, "userId"),
        new Claim("name", "John Doe"),
    };
    var identity = new ClaimsIdentity(claims, "TestAuthType");
    var claimsPrincipal = new ClaimsPrincipal(identity);
    

    And I'm not sure what you are testing here. Certainly "John Doe" will not be part of viewResult.Content because it is never been set to this.

    0 讨论(0)
  • 2020-12-15 03:31

    First, you are missing this line in your test:

    Thread.CurrentPrincipal = cp.Object;  
    

    (and then cleaning it up in TearDown).

    Second, as @trailmax mentioned, mocking principal objects is impractical. In your case, ClaimsPrincipal.FindFirst (according to decompiled source) looks into private fields of its instance, that's the reason mocking didn't help.

    I prefer using two simple classes that allow me to unit test claims-based functionality:

        public class TestPrincipal : ClaimsPrincipal
        {
            public TestPrincipal(params Claim[] claims) : base(new TestIdentity(claims))
            {
            }
        }
    
        public class TestIdentity : ClaimsIdentity
        {
            public TestIdentity(params Claim[] claims) : base(claims)
            {
            }
        }
    

    then your test shrinks down to:

        [Test]
        public void TestGetName()
        {
            // Arrange
            var sut = new HomeController();
            Thread.CurrentPrincipal = new TestPrincipal(new Claim("name", "John Doe"));
    
            // Act
            var viewresult = sut.GetName() as ContentResult;
    
            // Assert
            Assert.That(viewresult.Content, Is.EqualTo("John Doe"));
        }
    

    and it now passes, I've just verified.

    0 讨论(0)
提交回复
热议问题