使用WireMock来解除单测代码中的三方rest接口依赖
引言
在单元测试中,最烦的问题无非是外部接口不稳定、跨网不可达或者性能限制,碰上这种情况,有一些解决方案,
方案一,比较简单的实现,是mock掉这个接口相关的方法,让方法返回想要预期,但是这样的做法使得对应的复杂的接口调用类内部缺少覆盖,无法真正实现单元测试。
方案二,我们让我们的请求的(无论何种rest调用实现)按照我们的预期去返回。
今天我们要讨论的WireMock就可以实现方案二逻辑。
示例
wiremock还支持更多的条件设定,本示例采用最简单的mock来定义,其他条件配置可自行看wiremock文档。
上一个单测中的mock片段,本片段展示了localhost:999/ok 的请求会返回一个 ok。
rest实现部分 其中注解是我研发的基于注解的rest调用框架
代码语言:java复制@RestBean(host = "http://localhost:999/")
public interface GetDemo {
@Get(bodyType = BodyType.URL_PARAM, path = "ok")
String testPram(@Param("s") String ok);
@Get(bodyType = BodyType.URL_PLACE, path = "ok?pa={s}")
String testPlace(@Param("s") String ok);
}
junit wiremock部分
wireMockimport部分
代码语言:java复制import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
junit 部分
代码语言:txt复制 @Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(999));
private static final String RESULT = "ok";
@Before
public void setUp() {
wireMockRule.resetAll();
stubFor(get(urlEqualTo("/ok"))
.willReturn(aResponse().withBody(RESULT))
);
}
@Test
public void test() throws Exception {
String ret = getDemo.testPram("218ef17d5cc80d5b58c1df8f0e98fc57");
log.info("ret {}", ret);
Assert.assertTrue(ret.equals(RESULT));
String ret1 = getDemo.testPlace("218ef17d5cc80d5b58c1df8f0e98fc57");
log.info("ret {}", ret1);
Assert.assertTrue(ret1.equals(RESULT));
}
wiremock pom
代码语言:html复制 <dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.27.2</version>
</dependency>
总结
WireMock给我们带来的好处
上述例子中的testPram方法 如果在任何被逻辑中调用,均可以真正的执行,而不是虚假的mock 包含该请求逻辑的方法【mock单测】。
我们只需要care我们这次有哪些请求是需要被mock的,我们配置路径到wireMockConfig().port(999)对应的host端口【默认localhost:999,特殊需求除外】。
我们要做的只需要在module/src/test下 将原有外部host【如http://api.xx.com】改为本地【http://localhost:999】。
WireMock原理
WireMock是一个基于http api的模拟器,junit单测 @Before时,会根据WireMock 调用的stubFor进行Rest接口插桩。
然后在单元测试时可以直接访问该插桩的Rest接口,可以通过环境配置,定义junit单测环境,在junit单测环境中修改被测试的项目外部rest的baseUrl指向wiremock的微型服务,即可实现rest单测模拟。