2016-04-20 3 views
1

私は以下のコード行を見ることができません。私はモックしようとするとmock GetClaimsPrincipal()。Identity

ClaimsPrincipalFactory userClaimsPrincipal = new UserClaimsPrincipalFactory(); 
System.Security.Claims.ClaimsIdentity claimIdentity = userClaimsPrincipal.GetClaimsPrincipal().Identity as System.Security.Claims.ClaimsIdentity; 

、私は「System.NullReferenceException」種類の例外がMicrosoft.Owin.Host.SystemWeb.dllで発生したが、ユーザーコードで処理されなかったエラー

取得しています

以下のコードです。

public class UserClaimsPrincipalFactory : ClaimsPrincipalFactory 
{ 
    protected override ClaimsPrincipal OnGetClaimsPrincipal() 
    { 
     return HttpContext.Current.GetOwinContext().Authentication.User; 
    } 
} 

モック私はいずれかがこの上で私を助けて

Mock<UserClaimsPrincipalFactory> mockUserClaimsPrincipal = new Mock<UserClaimsPrincipalFactory>(); 
mockUserClaimsPrincipal 
    .Setup(ucp => ucp.GetClaimsPrincipal().Identity).Returns("Need to set"); 

を試してみました。前もって感謝します。

+0

'ClaimsPrincipalFactory'はカスタムクラスですか?可能であれば、クラスの定義を含めることができます。 – Nkosi

+0

あなたは本当に何を試そうとしていますか? 'claimIdentity'はより大きなテストの一部として生成されていますか? – Nkosi

+0

その例外は 'HttpContext'への緊密な結合に関連しています – Nkosi

答えて

1

このクラスの具体的な実装であるため

ClaimsPrincipalFactory userClaimsPrincipal = new UserClaimsPrincipalFactory(); 
ClaimsIdentity claimIdentity = userClaimsPrincipal.GetClaimsPrincipal().Identity as ClaimsIdentity; 

あなたはclaimIdentity変数のために必要になった大きなテストの一部として使用されている以下のコードは...あなたはUserClaimsPrincipalFactory抽象化する必要がある場合しっかりあなたも(あなたがやるべきではありません。Don't mock HttpContext: He doesn't like to be mocked!HttpContextを嘲笑しない限り、あなたのテスト中にnullに思われるHttpContextに結合

最終目標は、あなたが抽象ClaimsPrincipal/ClaimsIdentity SERVにその要件を取得するために提供氷。

public interface IClaimsPrincipalFactory { 
    ClaimsPrincipal GetClaimsPrincipal(); 
} 

この方法では、HttpContextに直接依存することなくテストすることができます。以下のように見えることができますユニットテストを行っていると ここでの仮定は、あなたがClaimsPrincipalFactoryクラスの直接制御を持っており、それをリファクタリングすることができますということです

....

public abstract class ClaimsPrincipalFactory : IClaimsPrincipalFactory { 
    public ClaimsPrincipal GetClaimsPrincipal() { 
     ClaimsPrincipal result = OnGetClaimsPrincipal(); 
     //...other code 
     return result; 
    } 
    protected abstract ClaimsPrincipal OnGetClaimsPrincipal(); 
} 

....

[TestMethod] 
public void Factory_Should_Get_Claims_Principal() { 
    //Arrange 
    var fakeIdentity = new ClaimsIdentity(); 
    var mockUserClaimsPrincipal = new Mock<IClaimsPrincipalFactory>(); 
    mockUserClaimsPrincipal.Setup(ucp => ucp.GetClaimsPrincipal().Identity).Returns(fakeIdentity); 

    IClaimsPrincipalFactory userClaimsPrincipal = mockUserClaimsPrincipal.Object; 
    System.Security.Claims.ClaimsIdentity claimIdentity = userClaimsPrincipal.GetClaimsPrincipal().Identity as System.Security.Claims.ClaimsIdentity; 

    //Act 
    //...other code that uses the claimIdentity 


    //Assert 
    //...other assertions 
} 
1

Typemock Isolatorとすることができます。 Isolate.WhenCalled() mocks OnGetClaimsPrincipal()なので、HttpContextには全く触れず、必要な場合はClaimsPrincipalを返します。例を参照してください:

public void TestGetClaimsPrincipal() 
{ 
    //Arrange 
    var claims = new List<Claim>(); 
    claims.Add(new Claim(ClaimTypes.Name, "Name")); 
    claims.Add(new Claim(ClaimTypes.Email, "[email protected]")); 
    var myIdentity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie); 
    var myPrincipal = new ClaimsPrincipal(myIdentity); 
    var target = new UserClaimsPrincipalFactory(); 
    Isolate.NonPublic.WhenCalled(target, "GetClaimsPrincipal").WillReturn(myPrincipal); 

    //Act 
    var result = Isolate.Invoke.Method(target, "GetClaimsPrincipal") as ClaimsPrincipal; 

    //Assert 
    Assert.AreEqual("Name", result.Identity.Name); 
}