简体   繁体   English

使用moq的扩展方法的单元测试

[英]Unit test for extension method using moq

I have two extension method like the below, 我有两种扩展方法,如下所示,

public static string FindFirstValue(this ClaimsPrincipal principal, string claimType, bool throwIfNotFound = false)
{
    string value = principal.FindFirst(claimType)?.Value;
    if (throwIfNotFound && string.IsNullOrWhiteSpace(value))
    {
        throw new InvalidOperationException(
            string.Format(CultureInfo.InvariantCulture, "The supplied principal does not contain a claim of type {0}", claimType));
    }

    return value;
}

public static string GetObjectIdentifierValue(this ClaimsPrincipal principal, bool throwIfNotFound = true)
{
    return principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier", throwIfNotFound);
}

I have heard it is impossible to unit test extension methods as they are static. 我听说单元测试扩展方法是不可能的,因为它们是静态的。 Just wanted to check if anybody has an idea to unit test the above extension methods using Moq? 只是想检查是否有人有想法使用Moq对上述扩展方法进行单元测试?

Could anyone please point me to right direction? 有人可以指点我正确的方向吗?

I have heard it is impossible to unit test extension methods as they are static. 我听说单元测试扩展方法是不可能的,因为它们是静态的。

This is not generally true. 这通常正确。 If a static method does not rely on creating the dependencies it has inside her body and for a specific input gets a specific output, you can definitely unit test it. 如果一个静态方法依赖于它在她体内创建的依赖关系, 并且对于一个特定的输入获得一个特定的输出,你绝对可以对它进行单元测试。

In your case, you can avoid using Moq for unit testing these extensions methods. 在您的情况下,您可以避免使用Moq对这些扩展方法进行单元测试。 You could create instances of ClaimsPrincipal and test your extension methods using those instances. 您可以创建ClaimsPrincipal实例并使用这些实例测试扩展方法。 Below you will found some examples: 您将在下面找到一些示例:

[Test]
public void WhenClaimTypeIsMissingAndAvoidExceptions_FindFirstValue_Returns_Null()
{
    var principal = new ClaimsPrincipal();

    var value = principal.FindFirstValue("claim type value");

    Assert.IsNull(value);
}

[Test]
public void WhenClaimTypeIsMissingAndThrowExceptions_FindFirstValue_ThrowsException()
{
    var principal = new ClaimsPrincipal();

    var claimType = "claim type value";

    Assert.Throws(Is.TypeOf<InvalidOperationException>()
                    .And.Message.EqualTo($"The supplied principal does not contain a claim of type {claimType}")
                , () => principal.FindFirstValue(claimType, throwIfNotFound: true));
}

[Test]
public void WhenClaimTypeIsFound_FindFirstValue_ReturnsTheValue()
{
    var principal = new ClaimsPrincipal();
    principal.AddIdentity(new ClaimsIdentity(new List<Claim> {new Claim("type", "1234")}));

    var value = principal.FindFirstValue("type");

    Assert.AreEqual(value,"1234");
 }

Your extension method is a wrapper around FindFirst so that is the method you actually want to mock. 您的扩展方法是FindFirst的包装器,因此这是您实际想要模拟的方法。 You are lucky :), since ClaimPrincipal.FindFirst is virtual method it is possible to mock it. 你很幸运:),因为ClaimPrincipal.FindFirstvirtual方法,它可以模拟它。

//Arrange
var principal = new Mock<ClaimsPrincipal>();
principal
    .Setup(m => m.FindFirst(It.IsAny<string>()))
    .Returns(new Claim("name", "John Doe"));

//Act
string value = principal.Object.FindFirstValue("claimType", true);

//Assert
Assert.AreEqual("John Doe", value);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM