for a spring boot application that needs to be tested below is my query.
@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.....
}
}
My application calls an external service which now needs to be mocked.
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();
I am calling my controller API with MVC as part of springtest
@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();
}
}
What I am looking for is to somehow proxy or side effect
http://localhost:9600/external_host_path
and redirect all calls made for this host to a custom Utility class which provides response based on the request params to the external host programatically.
I have seen multiple examples for mockito, wireMock, mockwebserver, mockserver etc But most of them work on a given(static path)-when(static path called)-then(give static response). I have many calls through out the flow and I already have the logic of the utility class to generate responses for provided request arguments.
CodePudding user response:
Although I was not able to find a answer to redirect webserver request to sideEffect class, For now atleast managing by Mockito's MockBean and 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();
}
}
Will still have a lookout for a way (Maybe TestContainers with image creation on the fly that will create a server with my mockCode, so that i can use hostname of this one and replace with existing real hostname)