【问题标题】:How to use moq to test code that calls protected helpers如何使用最小起订量来测试调用受保护助手的代码
【发布时间】:2011-12-12 16:39:56
【问题描述】:

我目前运行的测试如下所示:

// In Blah.cs
public class ClassUnderTest

{

    public bool MethodUnderTest()

    {

        // Do a bunch of stuff...

        return HelperMethod();

    }



    protected virtual bool HelperMethod()

    {

        bool success = false;

        // Proprietary Hardware Access.

        // Database Calls.

        // File System Modifications.

        return success;

    }

}


// In TestBlah.cs

public class TestStub : ClassUnderTest

{

    public bool HelperMethodReturnValue;



    protected override bool HelperMethod()

    {

        return HelperMethodReturnValue;

    }

}



[TestClass]

public class TestingClass

{

    [TestMethod]

    public void ClassUnderTest_MethodUnderTest_TestHelperReturnsTrue()

    {

        var stub = new TestStub();

        stub.HelperMethodReturnValue = true;

        Assert.IsTrue(stub.MethodUnderTest());

    }



    [TestMethod]

    public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse()

    {

        var stub = new TestStub();

        stub.HelperMethodReturnValue = false;

        Assert.IsFalse(stub.MethodUnderTest());

    }

}

上面的内容对于简单的事情看起来不错,但是存根类会迅速变得更大和更复杂。 我想使用 Moq 替换存根类。但是这不会编译,因为由于某种原因我无法在受保护的方法上设置返回值。

[TestMethod]

public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse()

{

    var mockClass = new Mock<ClassUnderTest>();
    mockClass.Protected().Setup("HelperMethod").Returns(false);

    Assert.IsFalse(mockClass.Object.MethodUnderTest());

}

有人知道我会怎么做吗?我可以用最小起订量做到这一点吗?

【问题讨论】:

  • 这里似乎有些不对劲......你没有模拟你的 SUT,你模拟了它的依赖关系。
  • 是的,实际上 Yojin 模拟了 SUT 以替换 SUT 中应该分开的部分,而不是在受保护的辅助方法中。

标签: c# unit-testing moq


【解决方案1】:

看看moq source code,我您需要显式调用通用版本的Setup。非泛型版本似乎用于 void 方法。所以试试

mockClass.Protected().Setup<bool>("HelperMethod").Returns(false);

除此之外,我建议您重新考虑您的课程设计。如果 HelperMethod() 正在做这么多事情,那么将它自己的类作为依赖注入到 ClassUnderTest 中是值得的。测试模拟对象,而不是使用模拟对象来测试“真实”的东西,并不是模拟框架的目的(至少一开始不是)。

【讨论】:

    【解决方案2】:

    受保护的方法并不是隔离依赖关系的好方法,但有时确实会出现这种情况,尤其是在调整遗留代码以实现可测试性时。避免笨拙的基于字符串的 Moq 语法的一种选择是使方法“受保护的内部”(如果您不打算在其他程序集的正常使用中覆盖它,则只是“内部”。)然后在程序集上使用 InternalsVisibleTo暴露方法。这有点骇人听闻,但是为此目的使用受保护的方法已经有点骇人听闻了。在某些方面,我更喜欢“内部”方法,因为它清楚地表明这是您不应该使用的后门方法(测试除外),而不是您可能希望正常覆盖的受保护方法用法。

    【讨论】:

      猜你喜欢
      • 2018-09-06
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 2011-06-23
      相关资源
      最近更新 更多