是否有任何工具可以自动化存根模拟对象响应? (使用jmock,mockito或easy mock)

时间:2013-04-23 19:34:02

标签: mocking mockito easymock powermock

问题:是否有任何工具可以自动化存根或模拟对象响应(使用jmock,mockito或easy mock)?

我必须针对依赖于Amazon AWS服务(SQS / Simple Queue Service和DynamoDB)的方法编写单元测试。对我来说,对模拟对象的反应往往非常乏味且难以维护。所以,我认为如果我们使用Java代理(通过CGLib或javassist)记录和重放存根响应会很好。我想过自己实现这样一个想法,但我想检查是否有人曾经实现过这样的想法。

3 个答案:

答案 0 :(得分:1)

easymock在过去的确做到了这一点,但我们发现随着代码的变化,这些测试往往会变得脆弱。我的经验是,如果在测试中维护存根是繁琐的,那么这就是应该听取的测试代码设计的线索。那里可能应该有更小的物体。

答案 1 :(得分:1)

我建议不要完全这样做。嘲笑你不拥有的图书馆只是在寻找麻烦(正如你已经看到的那样)并且只是以你认为你应该的方式确认你正在与图书馆互动。

如果您有与SQS / DynamoDb交互的代码,那么编写实际上会触及SQS和DynamoDb的集成测试 - 它们将比单元测试具有更高的置信度并且不会脆弱。 DynamoDb还有一个内存中的本地实例,你可以为此目的而旋转

答案 2 :(得分:0)

我考虑过相同的功能,最终我自己在Mockito框架而不是CGLib上直接实现它。我听说有人在Android Java平台上启用了Mockito,这样我就可以轻松移植在Android上使用Mockito的工具。但是,据我所知,我们目前无法移植任何依赖于CGLib或Javaassit的函数。

我开源了名为“bimock”的工具(双向模拟),它有两种模式。在记录模式下,它将带有返回值或异常的方法调用记录到JSON格式的资源文件中。在重放模式下,它在启动时设置方法调用和资源文件中的答案,并重放返回或抛出的答案。请参阅此示例,其中我记录了Java对象的公共方法响应,并从JSON文件中重放它们。

您应该能够针对各种依赖项使用此工具,不仅适用于Amazon AWS SDK对象,还适用于HKMap,ArrayList,ByteBuffer等JDK对象。

public class BimockTest {
    private Mode mode = Mode.Replay;
    private PojoMapper pojoMapper = new PojoMapper(new BimockModule());
    private Bimock bimock = new Bimock(pojoMapper);

    @Test
    public void testRecordAndReplayMap() throws IOException {
        val map = bimock.of(new HashMap<String, Integer>(), mode, new File("src/test/resources/test-record-and-replay-map.json"));
        assertThat(map.put("abc", 3), equalTo(null));
        assertThat(map.size(), equalTo(1));
        assertThat(map.get("abc"), equalTo(3));
    }

    @Test
    public void testRecordAndReplayList() {
        List<Long> list = new ArrayList<Long>();
        list = bimock.of(list, mode, new File("src/test/resources/test-record-and-replay-list.json"));
        try {
            assertThat(list.remove(-1), nullValue());
            fail();
        } catch (ArrayIndexOutOfBoundsException e) {
            assertThat(e.getMessage(), equalTo("-1"));
        }
        assertThat(list.add(100L), equalTo(true));
        assertThat(list.toArray(new Long[1]), equalTo(new Long[] { 100L }));
    }
}