MockServer 是一款功能强大的开源工具,专为模拟 HTTP 和 HTTPS 请求与响应设计,广泛应用于接口测试和开发联调。在实际测试中,经常需要针对同一请求返回不同响应,例如验证客户端重试机制、检查状态流转逻辑或模拟复杂业务场景。本文深入讲解如何利用 MockServer 实现同一请求的多响应模拟,帮助测试工程师高效应对多样化测试需求,特别适合小八超市的商品查询接口测试场景。

概述

MockServer 支持灵活的请求匹配、动态响应配置和延迟模拟,能够模拟、代理和记录 HTTP/HTTPS 交互。其强大的功能使其成为测试和开发中的得力助手,尤其在接口未就绪或需要验证异常场景时表现尤为出色。

MockServer 的优势

MockServer 的设计旨在提升开发和测试效率,其核心优势包括:

应用场景

MockServer 在以下场景中表现尤为出色:

启动 MockServer

MockServer 支持多种启动方式,包括 Docker、Java 应用程序或 Maven 插件。以下以 Docker 为例,展示快速启动方法,适合本地测试环境:

docker run -d -p 1080:1080 mockserver/mockserver

此命令的含义如下:

启动后,可通过 http://localhost:1080 访问 MockServer 的管理界面,或使用 REST/Java API 配置期望(Expectation)。例如,在小八超市测试中,可快速配置 /websocket 路径的模拟响应。

模拟多个响应

MockServer 通过 ExpectationTimes 配置,支持同一请求按顺序返回多个不同响应,非常适合测试动态流程、重试机制或异常处理。以下以小八超市的商品查询接口为例,展示如何配置多响应。

Java API 配置多响应

以下代码使用 MockServer 的 Java 客户端,针对 /websocket 路径的 POST 请求,配置三次不同响应,模拟正常、库存不足和超时场景:

package org.funtester.performance.books.chapter05.section5;

import org.mockserver.client.MockServerClient;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;

import java.util.concurrent.TimeUnit;

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

/**
 * FunTester MockServer 多响应示例
 */
public class MockServerMultipleResponses {

    public static void main(String[] args) {
        try (MockServerClient client = new MockServerClient("localhost", 1080)) {
            // 定义请求匹配:POST /websocket,特定请求体
            HttpRequest request = request()
                    .withMethod("POST")
                    .withPath("/websocket")
                    .withBody("{\"name\":\"西瓜\",\"index\":1}");

            // 第一个响应:正常价格和库存
            client.when(request, org.mockserver.model.Times.exactly(1))
                    .respond(response()
                            .withStatusCode(200)
                            .withBody("{\"Name\":\"西瓜\",\"Price\":45,\"Size\":62,\"Timestamp\":1701589121943}")
                            .withDelay(new org.mockserver.model.Delay(TimeUnit.SECONDS, 1)));

            // 第二个响应:库存不足
            client.when(request, org.mockserver.model.Times.exactly(1))
                    .respond(response()
                            .withStatusCode(200)
                            .withBody("{\"Name\":\"西瓜\",\"Price\":45,\"Size\":0,\"Timestamp\":1701589121944}")
                            .withDelay(new org.mockserver.model.Delay(TimeUnit.SECONDS, 2)));

            // 第三个响应:模拟超时
            client.when(request, org.mockserver.model.Times.exactly(1))
                    .respond(response()
                            .withStatusCode(504)
                            .withBody("{\"error\":\"FunTester: Gateway Timeout\"}")
                            .withDelay(new org.mockserver.model.Delay(TimeUnit.SECONDS, 5)));

            System.out.println("FunTester: MockServer 配置完成,等待请求...");
        }
    }
}

代码解读

测试效果:

使用 curl 或 Postman 测试:

curl -X POST http://localhost:1080/websocket -d '{"name":"西瓜","index":1}'

输出结果依次为:

这种序列化响应设计能有效模拟动态业务场景,例如库存逐渐减少或服务端异常。

REST API 配置多响应

MockServer 支持通过 REST API 配置期望,适合脚本化操作或 CI/CD 集成。以下是等效的 REST 请求示例:

curl -X PUT "http://localhost:1080/mockserver/expectation" -d '[
    {
        "httpRequest": {
            "method": "POST",
            "path": "/websocket",
            "body": "{\"name\":\"西瓜\",\"index\":1}"
        },
        "httpResponse": {
            "statusCode": 200,
            "body": "{\"Name\":\"西瓜\",\"Price\":45,\"Size\":62,\"Timestamp\":1701589121943}",
            "delay": {
                "timeUnit": "SECONDS",
                "value": 1
            }
        },
        "times": {
            "remainingTimes": 1
        }
    },
    {
        "httpRequest": {
            "method": "POST",
            "path": "/websocket",
            "body": "{\"name\":\"西瓜\",\"index\":1}"
        },
        "httpResponse": {
            "statusCode": 200,
            "body": "{\"Name\":\"西瓜\",\"Price\":45,\"Size\":0,\"Timestamp\":1701589121944}",
            "delay": {
                "timeUnit": "SECONDS",
                "value": 2
            }
        },
        "times": {
            "remainingTimes": 1
        }
    },
    {
        "httpRequest": {
            "method": "POST",
            "path": "/websocket",
            "body": "{\"name\":\"西瓜\",\"index\":1}"
        },
        "httpResponse": {
            "statusCode": 504,
            "body": "{\"error\":\"FunTester: Gateway Timeout\"}",
            "delay": {
                "timeUnit": "SECONDS",
                "value": 5
            }
        },
        "times": {
            "remainingTimes": 1
        }
    }
]'

解读

总结

MockServer 的多响应模拟功能为接口测试提供了极大便利,无论是 HTTP 还是 WebSocket 协议,都能灵活应对动态流程、异常处理和性能测试需求。在小八超市的测试场景中,MockServer 可模拟商品查询接口的多种响应状态,帮助验证客户端的鲁棒性和用户体验。通过 Java API 和 REST API,测试人员可以快速配置复杂测试场景,并无缝集成到自动化测试流程中。无论是开发联调、性能测试还是混沌工程,MockServer 都能游刃有余,成为测试工程师的得力助手。

FunTester 原创精华
从 Java 开始性能测试
故障测试与 Web 前端
服务端功能测试
性能测试专题
Java、Groovy、Go
测试开发、自动化、单测&白盒
测试理论、FunTester 风采
视频专题


↙↙↙阅读原文可查看相关链接,并与作者交流