0

我正在测试一个带有多个参数的函数,并根据它们的值调用不同的私有方法。

我想检查该函数是否始终调用正确的私有方法。

因为我知道私有方法会做什么,所以我可以检查最终结果,但是直接检查是否调用了正确的函数会更方便,因为我已经测试了私有方法。

有没有办法用存根替换 privae 方法?

4

6 回答 6

2

是的,有一些模拟库可以让你做到这一点。一个是PowerMock。从他们的私有方法教程中,你需要这样的东西:

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyUnit.class)
public class TestMyUnit {

    @Test
    public void testSomething() {
        MyUnit unit = PowerMock.createPartialMock(MyUnit.class, "methodNameToStub");
        PowerMock.expectPrivate(unit, "methodNameToStub", param1).andReturn(retVal);

        EasyMock.replay(unit);

        unit.publicMethod(param1);

        EasyMock.verify(unit);

    }

}

但是,我自己真的不同意这种做法。您的单元测试应该测试输入、输出和副作用,仅此而已。通过确保正确调用私有方法,您所做的就是防止您的代码被轻易重构。

换句话说,如果你想改变的单位的工作方式怎么办?执行此操作的安全方法是确保代码处于(通过)测试中,然后重构代码(可能包括更改调用的内部方法),然后再次运行测试以确保您没有破坏任何东西。使用您的方法,这是不可能的,因为您的测试测试的是确切的实现,而不是单元本身的行为。重构几乎总是会破坏测试,那么测试到底能给你带来多少好处呢?

大多数情况下,您会想要这样做,因为您实际上将这些私有视为自己的一个单元(这听起来像您,因为您说您已经直接测试了这些私有方法!)。如果是这种情况,最好将该逻辑提取到它自己的类中,对其进行测试,然后在剩余的代码中与该新单元的模拟/存根版本进行交互。如果你这样做了,你的代码就会有更好的结构,而且你不需要依赖 PowerMock 的巫术魔法。进行此类重构的绝佳参考是 Michael Feathers 的Working Effectively with Legacy Code

于 2012-04-18T16:21:43.797 回答
0

如果调用正确的“私有方法”没有可观察到的外部结果,您确定要对此进行测试吗?也许不应该。

如果无论是否调用私有方法,最终结果都相同,并且您仍想观察其调用,则可以将该方法设为公共并将其移至其自己的类,然后模拟该类。然后你可以验证(使用 Mockito 或类似的框架)你的方法是否被调用。

于 2012-04-18T16:24:47.183 回答
0

代码覆盖工具通过在测试实际运行之前重写字节码来做这种事情。所以,它必须是可能的,但它不是微不足道的。

更新:编写一个要求调用“正确”私有方法的单元测试会使重构工作变得非常痛苦,因为那时您必须重新编写所有测试。这违背了测试的目的。

于 2012-04-18T16:26:19.727 回答
0

作为解决方案之一,可以使用内部类的代理。您需要在每个必须测试的类中添加内部类。但对于大型产品项目来说,这不是很好的解决方案。它需要创建添加脚本以从您的发布文件(jar/war)中删除生成的类。

但更简单的方法将使用 PowerMock,如下面的评论(或上层:)) - http://code.google.com/p/powermock/wiki/MockPrivate

于 2012-04-18T16:22:58.173 回答
0

您可以检查 java 仪器以执行此操作

于 2012-04-18T16:18:40.400 回答
0

是否有可能为所讨论的类提供另一个对象,将私有方法移至该对象并使其公开?在这种情况下,很容易为该接口创建一个测试假人。

于 2012-04-18T16:23:27.787 回答