将请求重定向到 Side_Effect 实用程序类

Posted

技术标签:

【中文标题】将请求重定向到 Side_Effect 实用程序类【英文标题】:Re-direct requests to SideEffect Utility Classes 【发布时间】:2022-01-11 13:15:36 【问题描述】:

对于需要在下面测试的 Spring Boot 应用程序是我的查询。

@CustomLog
@RestController
@RequestMapping("/my_path")
public class MyController 
    @GetMapping(path = "**", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<JsonNode> fetchData(HttpServletRequest request)
      ... some code.....which also calls external apis.....
      
    @PostMapping(path = "**", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<Map<String, Object>> createMOI(HttpServletRequest request)
          ... some code.....which also calls external apis.....
      
    

我的应用程序调用了现在需要模拟的外部服务。

this.webClient = WebClient.builder().baseUrl("http://localhost:9600/external_host_path")
                .defaultHeader(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON_VALUE)
                .build();
Mono<Pojo>responseMo = webClient.post().uri("/aGivenSubPath")
                       .accept(MediaType.APPLICATION_JSON).bodyValue(requestPoJo)
                       .retrieve().bodyToMono(Pojo.class).block();

作为 springtest 的一部分,我正在使用 MVC 调用我的控制器 API

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyControllerTest 
  @Autowired
  MyController controller;
  @Before
  public void setup() throws Exception 
    this.mockMvc = standaloneSetup(this.controller).build();
  
  @Test
  public void testControl() throws Exception 
    mockMvc
    .perform(post("http://localhost:9600/my_path")
    .contentType(MediaType.APPLICATION_JSON)
    .content("'someData':'[]'"))
    .andExpect(status().isAccepted())
  .andReturn();
  

我正在寻找的是某种代理或副作用

http://localhost:9600/external_host_path

并将对该主机的所有调用重定向到自定义实用程序类,该实用程序类根据请求参数以编程方式向外部主机提供响应。

我已经看到了 mockito、wireMock、mockwebserver、mockserver 等多个示例 但是它们中的大多数都在给定的(静态路径)-何时(调用静态路径)-然后(给出静态响应)上工作。 在整个流程中我有很多调用,并且我已经拥有实用程序类的逻辑来为提供的请求参数生成响应。

【问题讨论】:

【参考方案1】:

虽然我无法找到将网络服务器请求重定向到 sideEffect 类的答案, 目前至少由 Mockito 的 MockBean 和 Answer 管理。

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyControllerTest 
  @Autowired
  MyController controller;
  @MockBean
  MyExternalServiceClient serviceClient;
  @Autowired
  MySideEffectService sideEffect;
  @Before
  public void setup() throws Exception 
    this.mockMvc = standaloneSetup(this.controller).build();     
    Mockito.when(serviceClient.getMethod(any(),anyBoolean())).thenAnswer((Answer) invocation -> 
        Object[] args = invocation.getArguments();
        Object mock = invocation.getMock();
        return sideEffect.getMethod((Map<String, List<String>>) args[0], (Boolean) args[1]);
    );
  
  @Test
  public void testControl() throws Exception 
    mockMvc
    .perform(post("http://localhost:9600/my_path")
    .contentType(MediaType.APPLICATION_JSON)
    .content("'someData':'[]'"))
    .andExpect(status().isAccepted())
  .andReturn();
  

仍然会寻找一种方法(也许 TestContainers 可以即时创建图像,它将使用我的 mockCode 创建一个服务器,以便我可以使用这个主机名并替换为现有的真实主机名)

【讨论】:

以上是关于将请求重定向到 Side_Effect 实用程序类的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Spring 请求重定向到另一个应用程序?

将所有请求 HTTP 重定向到 HTTPS [重复]

如何将所有访客请求重定向到 Laravel 应用程序中的登录页面?

超实用的14个 Spring MVC “隐藏”技巧,用了都说好!

超实用的14个 Spring MVC “隐藏”技巧,用了都说好!

将 POST 请求从一个 REST API 转发/重定向到另一个