问题:是否有任何工具可以自动化存根或模拟对象响应(使用 jmock、mockito 或 easy mock)?
我必须针对依赖于 Amazon AWS 服务(SQS/Simple Queue Service 和 DynamoDB)的方法编写单元测试。对我来说,存根模拟对象响应往往非常乏味且难以维护。所以,我认为如果我们使用 Java 代理(通过 CGLib 或 javassist)记录和重放存根响应会很好。我想过自己实施这样的想法,但我想检查是否有人曾经实施过这样的想法。
我建议不要完全这样做。嘲笑您不拥有的库只是自找麻烦(正如您已经看到的那样),并且只会确认您正在以您认为应该的方式与库进行交互。
如果您有与 SQS/DynamoDb 交互的代码,那么编写实际运行并命中 SQS 和 DynamoDb 的集成测试 - 它们会给您比单元测试更高的信心,并且不会脆弱。DynamoDb 还有一个内存本地实例,您可以为此目的启动
easymock 在过去就是这样做的,但是我们发现随着代码的变化,这样的测试往往会变得脆弱。我的经验是,如果在测试中维护存根很乏味,那么这就是关于应该听取测试代码设计的线索。那里可能应该有更多更小的物体。
我考虑了相同的功能,最终我自己通过 Mockito 框架而不是 CGLib 直接实现它。听说有人在 Android Java 平台上启用了 Mockito,这样我就可以轻松地将我的使用 Mockito 的工具移植到 Android 上。但是,据我所知,目前我们无法移植任何依赖于 CGLib 或 Javaassit 的函数。
我已经开源了我的名为“ bimock ”(双向模拟)的工具,它有两种模式。在记录模式下,它将带有返回值或异常的方法调用记录到 JSON 格式的资源文件中。在重放模式下,它在启动时从资源文件中设置方法调用和答案,并重放返回或抛出的答案。请参阅此示例,其中我记录了 Java 对象的公共方法响应并从 JSON 文件中重放它们。
您应该能够使用此工具来处理各种依赖项,不仅适用于 Amazon AWS 开发工具包对象,还适用于 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 }));
}
}