首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hoverfly修改Response?啪啪被打脸

Hoverfly修改Response?啪啪被打脸

作者头像
Antony
发布2021-04-28 10:36:46
3220
发布2021-04-28 10:36:46
举报

在之前的一文中 ,笔者介绍了如何通过SimulationPreprocessor这个接口来实现对Hoverfly录制的请求数据Request进行修改。

当时还立了一个flag,说这个套路也适合对响应数据Response进行修改。

例如,有这样的一个案例,

"response": {
   "status": 200,
   "body": "{\"bookingId\":\"1\",\"origin\":\"London\",\"destination\":\"Singapore\",\"time\":\"[NOW]\",\"_links\":{\"self\":{\"href\":\"http://localhost/api/bookings/1\"}}}",

在响应的body中,希望time这个字段可以返回动态时间,如当前系统时间,而不是一个固定录制的值。因此,将具体值用一个占位符[NOW]进行了替换。

然后写了一个类来实现这个替换。

static class TimeSimulationPreprocessor implements SimulationPreprocessor {
    @Override
    public void accept(Simulation simulation) {
       HoverflyData originData= simulation.getHoverflyData();
        Set<RequestResponsePair> pairs= new HashSet<>();
        originData.getPairs().stream()
                .forEach(p ->
                {

    Response origin= p.getResponse();
                  String body =origin.getBody();
          String replaced=    body.replace("[NOW]", LocalDateTime.now().toString());
      Response rsp= new Response(origin.getStatus(),replaced,origin.isEncodedBody(),origin.isTemplated(),origin.getHeaders(),origin.getTransitionsState(),origin.getRemovesState(),origin.getFixedDelay(),origin.getLogNormalDelay());  RequestResponsePair pair =new RequestResponsePair(p.getRequest(),rsp);
   pairs.add(pair);
                });
  //HoverflyData  hoverflyData=new HoverflyData(pairs,simulation.getHoverflyData().getGlobalActions());
  // simulation.setHoverflyData(hoverflyData);
   simulation=new Simulation(new HoverflyData(pairs,simulation.getHoverflyData().getGlobalActions()), simulation.getHoverflyMetaData());
        ObjectMapper mapper = new ObjectMapper();
        try {
            System.out.println("class::\n"+mapper.writeValueAsString(simulation));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

}

可以发现,这个过程相比之前的修改request,繁琐了很多。当时还为在意,然后写一个用例测试一下,

package io.specto.hoverfly.junit5;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.specto.hoverfly.junit.core.Hoverfly;
import io.specto.hoverfly.junit.core.SimulationPreprocessor;
import io.specto.hoverfly.junit.core.SslConfigurer;
import io.specto.hoverfly.junit.core.model.*;
import io.specto.hoverfly.junit5.api.HoverflyConfig;
import io.specto.hoverfly.junit5.api.HoverflySimulate;
import okhttp3.OkHttpClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
@HoverflySimulate(
        config = @HoverflyConfig(
                simulationPreprocessor = PreProcessResponseTest.TimeSimulationPreprocessor.class
        ),        source = @HoverflySimulate.Source(value = "hoverfly/test-service.json",
        type = HoverflySimulate.SourceType.CLASSPATH)
)
@ExtendWith({HoverflyExtension.class})
public class PreProcessResponseTest {
    private static OkHttpClient client;
    @BeforeAll
    static void init(Hoverfly hoverfly) {
        SslConfigurer sslConfigurer = hoverfly.getSslConfigurer();
        client = new OkHttpClient.Builder()
                .sslSocketFactory(sslConfigurer.getSslContext().getSocketFactory(), sslConfigurer.getTrustManager())
                .build();
    }
    @Test
    void shouldUseCustomPorts(Hoverfly hoverfly) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println("test::\n"+mapper.writeValueAsString(hoverfly.getSimulation()));
        final okhttp3.Request request = new okhttp3.Request.Builder().url("https://www.my-test.com/api/bookings/1")
                .build();
        final okhttp3.Response response = client.newCall(request).execute();
        System.out.println("test::\n"+mapper.writeValueAsString(response.body().string()));
        assertThatJson(response.body().string()).node("bookingId").isStringEqualTo("1");
    }
}

然后就被打脸了。。。

这个数据压根就没有被修改。虽然在预处理的类里面仿佛已经修改了。

看上去,Hoverfly在设计时就没打算让你修改Response。

1、Simluation类里面只有getHoverflyData方法,而没有set

simulation.setHoverflyData(hoverflyData);

这个方法是笔者自己改的源码。

2、接下来的HoverflyData、RequestResponsePair、Response一水全是只提供构造方法,然后成员变量全部final, 只提供getXXX,不提供setXXX方法。

public class Response {
    private final Integer status;
    private final String body;
    private final boolean encodedBody;
    private final boolean templated;
    private final Map<String, List<String>> headers;
    private final Map<String, String> transitionsState;
    private final List<String> removesState;
    private final Integer fixedDelay;
    private final LogNormalDelay logNormalDelay;
    @JsonCreator
    public Response(
            @JsonProperty("status") Integer status,
            @JsonProperty("body") String body,
            @JsonProperty("encodedBody") boolean encodedBody,
            @JsonProperty("templated") boolean templated,
            @JsonProperty("headers") Map<String, List<String>> headers,
            @JsonProperty("transitionsState") Map<String, String> transitionsState,
            @JsonProperty("removesState") List<String> removesState,
            @JsonProperty("fixedDelay") Integer fixedDelay,
            @JsonProperty("logNormalDelay") LogNormalDelay logNormalDelay)//...
}

看上去,要实现这样的需求,

1、要么自己fork一个Hoverfly-java,然后提供一个setHoverflyData方法,或者去修改Response等类。

2、说服Hoverfly-java团队修改设计?

3、用 middleware (python脚本 )注册到Hoverfly。。。用系统测试的套路来搞集成测试。

看来话不能说太满

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档