浅谈 Mock Server

What?什么是 Mock Server

Mock 是模拟的意思。在测试中,通常表述为:对测试过程中不容易构造或者不容易获取的物件,用一个虚拟的物件来进行模拟的一个过程。能够提供 Mock 功能的服务就叫作 Mock Server。 Mock Server 通过模拟真实的服务,提供对来自客户端请求的真实响应。

Why?为什么要用 Mock Server

  1. 在开发初期先模拟外部接口,避免直接使用实际外部接口进行开发调试,提高开发效率
  2. 全面准确的模拟外部接口的返回,提高自身代码的可靠性,提升验证的全面性

How?怎么用 Mock Server

主要包括两种使用方式,一种是通过一个现成的 Mock Server 服务,这种的好处是对代码无侵入,只需要将调用的 URL 修改为 Mock Server 提供的 URL 即可。另一种是在代码里面显式的编写相关的规则,这样的好处是不再需要单独启用服务,在代码里面就可以完成 Mock,主要在单测的时候使用。

使用方式一:通过现成的服务打桩

可以使用类似 apifox 工具本地/线上打桩,apifox 不仅有基于 Swgger 的 API 管理的能力,同时也具备 API Mock 的功能。具体使用方法可以访问: https://www.apifox.cn/

使用方式二:通过代码打桩

MockServer 官方文档 http://www.mock-server.com
Maven 引入

<dependency>
    <groupId>org.mock-server</groupId>
    <artifactId>mockserver-netty</artifactId>
    <version>5.4.1</version>
</dependency>
<dependency>
    <groupId>org.mock-server</groupId>
    <artifactId>mockserver-client-java</artifactId>
    <version>5.4.1</version>
</dependency>

示例一

ClientAndServer 用法

package com.yzy.mock;

import org.mockserver.integration.ClientAndServer;
import org.mockserver.model.Cookie;

import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
import static org.mockserver.model.Parameter.param;

public class MockServer {
    public static void main(String[] args) {
        ClientAndServer server = new ClientAndServer(1080);
        server.when(
                request()
                        .withMethod("GET")
                        .withPath("/test")
                        .withQueryStringParameters(
                                param("p", "1")
                        )
        ).respond(
                response()
                        .withCookie(new Cookie("cKey", "cValue"))
                        .withBody("test1")
        );

        server.when(
                request()
                        .withMethod("GET")
                        .withPath("/test")
                        .withQueryStringParameters(
                                param("p", "2")
                        )
        ).respond(
                response()
                        .withBody("test2")
        );
    }
}

启动 main 方法,打开浏览器,输入 http://localhost:1080/test?p=1,页面返回test1,并且成功写入cookie。注意写入的cookie 是Session 级别的,会话关闭将消失。输入http://localhost:1080/test?p=2,页面返回 test2,说明 MockServer 同时监听的两个匹配都有效。

示例二

MockServerClient 用法

package mock;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.junit.Rule;
import org.junit.Test;
import org.mockserver.client.MockServerClient;
import org.mockserver.junit.MockServerRule;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;

public class MockServerTest {
    @Rule
    public MockServerRule server = new MockServerRule(this, 1080);

    @Test
    public void test() throws IOException {
        MockServerClient mockClient = new MockServerClient("localhost", 1080);
        String expected = "hello world";

        mockClient.when(
                request()
                        .withPath("/hello")
                        .withMethod("GET")
        ).respond(
                response()
                        .withStatusCode(200)
                        .withBody(expected)
        );

        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://localhost:1080/hello");
        CloseableHttpResponse response = client.execute(httpGet);

        //验证
        InputStream content = response.getEntity().getContent();
        InputStreamReader inputStreamReader = new InputStreamReader(content);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String responseText = bufferedReader.readLine();
        assertThat(responseText, equalTo(expected));
    }
}
posted @ 2022-10-07 21:40  hunterzhang  阅读(210)  评论(0编辑  收藏  举报