Java如何在java中模拟对象和静态方法?

时间:2011-10-01 08:44:06

标签: java mocking

我正在写一个CustomerHelper的junit,它在内部调用AccountHelper对象的方法。 CustomerHelper正在创建 AccountHelper对象,其中一个方法使用new运算符。现在,如果我想模拟AccountHelper对象。我有什么方法可以做到吗?

如果某个setter或构造函数注入了这个依赖项(本例中为AccountHelper),我可以设置我的MockAccountHelper。对吗? 但是,当我们使用New运算符创建依赖项时,有什么方法可以进行模拟吗?

第二个问题: - 无论如何我们可以使用核心java库来模拟静态方法而无需使用Power / Easy Mock吗?即使我进行了电源模拟,想要了解它是如何在内部进行简单的?< /强>

5 个答案:

答案 0 :(得分:1)

JMockit允许您轻松模拟静态方法和内部构造的对象。

你会做这样的事情:

@Test
public void testWhatever() {
    new Expectations() {
        AccountHelper accountHelper;
        {
            new AccountHelper();
            accountHelper.someMethod();
    }}
    objectUnderTest.doWhatever();
}

我不相信在核心Java库中存在模拟静态方法的内置方法。我也不确定内部发生了什么,但我认为JMockit会进行某种字节码级别的修改来动态替换类。

答案 1 :(得分:0)

在测试用例中,您需要一种方法将AccountHelper的模拟设置为CustomerHelper。因此,您的CustomerHelper类将需要AccountHelper的setter或可以传递所需AccountHelper的构造函数。 如果AccountHelper在方法中本地实例化,我想你无法设置模拟。您无法从外部访问它(例如您的junit测试用例),它的范围只是您方法的本地范围。

你不能模拟静态方法。我想模拟库使用一些字节码生成库(如。)来创建模拟动态 http://asm.ow2.org/index.html 要么 http://cglib.sourceforge.net/ 字节码框架将在运行时生成模拟类字节码。他们通过重写方法来做到这一点。但是静态方法不能被覆盖。

Tiberiu

答案 2 :(得分:0)

  

如果某个setter或构造函数注入了这个依赖项(本例中为AccountHelper),我可以设置我的MockAccountHelper.Right吗?但是,当我们使用New运算符创建依赖时,有什么方法可以做模拟吗?

是的 - 没错,但更重要的是注入对象是让对象类型实现一个接口,然后也可以通过模拟类型使用。没有任何明确界面的模拟类型的问题在于,在改变实现的同时创建保证原始合同的并行模拟类型并不容易。

我认为在你的情况下可能的唯一方法是创建一个扩展AccountHelperMock的新类型AccountHelper并覆盖所有方法(我希望它可以)。然后在您的代码中,手动将new AccountHelper()替换为new AccountHelperMock(),您可以在此处模拟此内容。

答案 3 :(得分:0)

有一个powermockito库可用于模拟测试类中的静态方法调用。 powermockito库的maven存储库是:

<dependency>
 <groupId>org.powermock</groupId>
 <artifactId>powermock-api-mockito</artifactId>
 <version>1.6.6</version>
</dependency>

如果您想了解有关powermockito的更多信息,请参阅a link

答案 4 :(得分:0)

在测试静态方法时,我使用以下代码结构。

Powermock.mockStatic(Something.class)

Something.someMethod(); // Static Method you want to mock
EasyMock.expectLastCall().andReturn(/*Whatever you want to return*/);

Powermock.replay(Something.class);

// Call which makes use of Something.someMethod

Powermock.verify(Something.class);

理想情况下,您不需要测试静态方法。 PowerMock是一个Java框架,允许您对通常被视为不可测试的代码进行单元测试。