简体   繁体   English

使用Moq,如何使用out参数模拟受保护的方法?

[英]With Moq, how can I mock protected methods with out parameter?

For a method like: 对于像这样的方法:

protected virtual bool DoSomething(string str) { }

I usually mock it through: 我经常嘲笑它:

var mockModule = new Mock<MyClass> { CallBase = true };
mockModule.Protected().Setup<bool>("DoSomething", ItExpr.IsAny<string>()).Returns(true);

But for a method like: 但对于像这样的方法:

protected virtual bool DoSomething(out string str) { }

How can I mock it? 我怎么嘲笑它?

It can be done since moq 4.8.0-rc1 (2017-12-08). 这可以从moq 4.8.0-rc1(2017-12-08)开始。 You can use ItExpr.Ref<string>.IsAny for match any value for ref or out parameters. 您可以使用ItExpr.Ref<string>.IsAny来匹配refout参数的任何值。 In your case: 在你的情况下:

mockModule.Protected().Setup<bool>("DoSomething", ItExpr.Ref<string>.IsAny).Returns(true);

Full example with mocking the out parameter: 模拟out参数的完整示例:

[TestClass]
public class OutProtectedMockFixture
{
    delegate void DoSomethingCallback(out string str);

    [TestMethod]
    public void test()
    {
        // Arrange
        string str;
        var classUnderTest = new Mock<SomeClass>();
        classUnderTest.Protected().Setup<bool>("DoSomething", ItExpr.Ref<string>.IsAny)
            .Callback(new DoSomethingCallback((out string stri) =>
                {
                    stri = "test";
                })).Returns(true);

        // Act
        var res = classUnderTest.Object.foo(out str);

        // Assert
        Assert.AreEqual("test", str);
        Assert.IsTrue(res);
    }
}

public class SomeClass
{
    public bool foo(out string str)
    {
        return DoSomething(out str);
    }

    protected virtual bool DoSomething(out string str)
    {
        str = "boo";
        return false;
    }
}

It can be done by using Typemock Isolator , you can mock your non-public methods and change their out and ref parameters easily: 它可以通过使用Typemock Isolator完成 ,您可以模拟非公共方法并轻松更改其out和ref参数:

[TestMethod, Isolated]
public void test()
{
    // Arrange
    string str;
    SomeClass classUnderTest = new SomeClass();
    Isolate.NonPublic.WhenCalled(classUnderTest, "DoSomething").AssignRefOut("test").IgnoreCall();

    // Act
    classUnderTest.foo(out str);

    // Assert
    Assert.AreEqual("test", str);
}


public class SomeClass
{
    public void foo(out string str)
    {
        DoSomething(out str);
    }

    protected virtual bool DoSomething(out string str) 
    {
        str = "boo";
        return true;
    }
}

you can read more about it here . 你可以在这里阅读更多相关信息。

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

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