Java/Junit mock系统外rest接口 - WireMock

2022-04-13 19:03:50 浏览数 (1)

使用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单测模拟。

0 人点赞