如何使用犀牛模拟来测试是否调用类的私人方法



我在c#和犀牛模拟都很新。我搜索并找到了与我的问题相似的主题,但找不到适当的解决方案。

我试图了解我的单位测试中是否调用了私有方法。我正在使用犀牛模拟,阅读许多有关它的文件,其中一些只是说将方法的访问说明符从私有到公共,但我无法更改源代码。我试图将源文件链接到我的测试项目,但没有更改。

  public void calculateItems()
    {
        var result = new Result(fileName, ip, localPath, remotePath);
        calculateItems(result, nameOfString);
    }
    private void calculateItems(Result result, string nameOfString )

从上面的代码中看到,我有两种方法具有完全相同的名称,即计算信息,但是公共一个没有参数,私有一个有两个参数。我试图理解当我在我的UNITDEST上称公共场所时,私人方法是否称为?

    private CalculateClass sut;
    private Result result; 
    [SetUp]
    public void Setup()
    {
      result = MockRepository.GenerateStub<Result>();
      sut = new CalculateClass();
    }
    [TearDown]
    public void TearDown()
    {
    }
    [Test]
    public void test()
    {     
        sut.Stub(stub => stub.calculateItems(Arg<Result>.Is.Anything, Arg<string>.Is.Anything));
        sut.calculateItems();
        sut.AssertWasCalled(stub => stub.calculateItems(Arg<Result>.Is.Anything, Arg<string>.Is.Anything));
    }

在我的统计上,我正在犯下一个错误,上面写着"没有过多的计算方法,请进行两个参数"。有没有一种方法可以在不更改源代码的情况下进行测试?

您正在测试错误的东西。私人方法是私人的。它们对消费代码无关,并且单位测试像其他任何人一样消耗代码。

在测试中,您可以测试并验证组件的外部面向功能。它的内部实现细节与测试无关。所有的测试都关心的是调用操作是否会产生预期的结果。

所以您必须问自己的问题是...调用此操作时的预期结果是什么?

calculateItems()

它没有返回任何东西,那么它会做什么?它以某种方式修改哪种状态?是您的测试需要观察到的,而不是实现细节,而是可观察到的结果。(如果操作没有可观察到的结果,则"通过"或"失败"之间没有区别,因此没有任何测试。)

我们看不到您的代码的详细信息,但是可观察的结果可能完全与另一个组件结合在一起。如果是这种情况,那么其他组件是此操作的依赖性,而单位测试的目标是模拟该依赖项,以便可以独立于依赖项测试操作。然后可能需要修改组件,以便提供依赖关系而不是内部控制。(这称为依赖性反转原理。)


也要注意...

但我无法更改源代码

这完全是一个不同的问题。如果您真的无法更改源代码,那么这些测试的值将大大降低并可能完全消除。如果测试失败,您该怎么办?没有什么。因为您无法更改代码。那么您正在测试什么?

请记住,不仅有可能,而且不幸的是非常常见的程序员编写代码,而不能进行有意义的单位测试。如果其他人向您提供此代码,并且由于某些非技术原因,您被禁止更改它,那么其他人将是其他人纠正代码的责任。"纠正"可能包括"使有意义的单位测试成为可能"。(或者,老实说,他们应该是单位测试。不是您。)

如果您的公共方法称您的私人方式然后,您的测试也会发生同样的事情。测试无非是可以运行和调试的代码,您可以尝试一下,因此请查看会发生什么。

私有方法不能直接测试,但是可以通过其公共呼叫者进行测试,这就是您正在做的事情,所以一切都很好。是否有这样的设置是一个好主意,这完全是另一回事,但我现在并不是这样。

现在,让我们讨论您实际测试的内容。

单元测试不应深入了解其测试的代码。原因是您应该拥有输入和输出,并且不应该在乎之间发生了什么。

如果您重构代码并消除了私有方法,那么您的测试也会破坏,即使您对公共方法的输入和输出保持不变。这不是一个好的位置,这就是我们所说的脆性测试。

因此,请添加围绕公共方法的功能测试,验证您获得的帽子您所期望的帽子,不必担心它是否调用您的私人方法。

当您说需要知道是否称呼私人方法时,这可以具有两种不同的解释:

  1. 您想确保在一个特定的测试中调用私有方法,这使其成为该测试的成功标准。

  2. 您想知道任何测试用例是否完全调用了私有方法。您可能对此感兴趣,因为您想确定您的测试套件是否涵盖了私人方法,或者正如您所说,只是要了解代码中实际发生的情况。

关于第二个解释:,如果您想了解代码中发生的事情,则一种很好的方法是使用调试器,然后逐步浏览代码以查看所谓的函数。由于我不是这里的C#专家,所以我不能建议任何特定的调试工具,但是在网络上找到有关此建议的一些建议并不困难。这种方法将满足您的要求,不需要更改源代码

另一种可能性,特别是如果您对测试是否涵盖的私人功能感兴趣,则是为C#使用测试覆盖工具。覆盖范围工具将向您展示是否调用了私有方法。同样,这不需要对源代码进行任何更改。

关于您的问题的第一个解释:如果要测试某些私有功能作为测试成功标准的一部分,则选择使用使用公共API的测试来执行此操作。然后,在这些测试中,您应该能够判断是否调用了私人功能,因为私有功能对测试结果的影响。

,与其他意见相比,您应该测试实施。单位测试的主要目标是在代码中找到错误。不同的实现有不同的错误。这就是为什么人们还使用覆盖工具,看看他们是否涵盖了实施的代码。而且,覆盖范围还不够,您还需要检查表达式的边界案例等。当然,在重构的情况下,进行可维护的测试和测试是不必要的目标(为什么通过公共API进行测试通常是一种很好的方法 - 但并非总是如此),但是与查找所有错误的目标相比,它们是次要目标。

最新更新