4

我想知道我是否可以模拟超类构造函数调用及其 super() 调用。

例如,我有以下课程

class A
{
    A(..)
    {
        super(..)
    }
}   

class B extends A
{
    B(C c)
    {
        super(c)
    }
}

所以,我打算对 B 类中的一些方法进行单元测试,但是在创建实例时,它确实调用了超类构造函数,这使得编写单元测试变得很困难。那么,我怎样才能模拟所有的超类构造函数调用。此外,我想模拟 A 类中的几个方法,以便它返回一些我需要的值。

谢谢!!

4

3 回答 3

1

您可以使用 PowerMock 库。当你需要完成像你这样的事情时,它真的是一个救命稻草。 https://github.com/powermock/powermock/wiki/Suppress-Unwanted-Behavior

于 2012-05-03T06:37:48.977 回答
1

模拟构造函数是一个非常糟糕的主意。这样做是为了规避生产中将发生的行为。这就是为什么在构造函数中做一些工作,比如启动线程和调用外部依赖,是一个设计缺陷

您能否诚实地说在构造函数中执行的工作对您尝试测试的行为没有影响?如果答案是否定的,您将冒着编写将在测试环境中通过但在生产中失败的测试的风险。如果答案是肯定的,那么将“工作”移到构造函数之外是一个简单的案例。另一种选择是将您尝试测试的行为移动到另一个类(可能是它自己的)。

如果您使用像 Guice 这样的 DI 框架(我假设是因为您以这种方式标记它),则更是如此。

于 2012-05-03T22:53:07.300 回答
0

您的问题的简短回答是“不完全正确”。您不能“模拟”构造函数,更不用说超级了。对于我熟悉的模拟框架,模拟 super.anyMethod 也很困难或不可能。Powermock确实允许您抑制超级构造函数和有问题的方法,这与模拟它们并不完全相同,但可能会有所帮助。

当 B 扩展 A 时,它当然与 A 完全耦合。这本身不是问题,但它可以,而且看起来就在这里。不要让 B 扩展 A,而是尝试让 B 包含一个 A(如果需要,可能实现相同的接口)。然后你可以注入一个模拟 A 并委托所有你想要的调用。那会更容易进行单元测试,不是吗?

在测试期间在设计中发现这些东西是测试驱动开发的好处之一。

于 2012-05-03T03:41:54.430 回答