【问题标题】:Is there any tool that automates stubbing mock object responses? (using jmock, mockito or easy mock)是否有任何工具可以自动存根模拟对象响应? (使用 jmock、mockito 或 easy mock)
【发布时间】:2013-04-23 19:34:02
【问题描述】:

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

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

【问题讨论】:

    标签: mocking mockito easymock powermock


    【解决方案1】:

    easymock 在过去正是这样做的,但我们发现随着代码的更改,此类测试往往会变得脆弱。我的经验是,如果在测试中维护存根很乏味,那么这就是关于应该听取测试代码设计的线索。那里可能应该有更多更小的物体。

    【讨论】:

      【解决方案2】:

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

      如果您有与 SQS/DynamoDb 交互的代码,那么编写实际运行并命中 SQS 和 DynamoDb 的集成测试 - 与单元测试相比,它们会给您更高的信心,并且不会脆弱。 DynamoDb 还有一个内存中的本地实例,您可以为此目的启动它

      【讨论】:

        【解决方案3】:

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

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

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

        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 }));
            }
        }
        

        【讨论】:

        • 当您可以使用示例中的任何类时,为什么还要模拟它们?就像史蒂夫在下面所说的那样,您只是在创建非常脆弱的测试,这些测试正在复制您的生产逻辑
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-15
        • 1970-01-01
        • 2016-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多