简体   繁体   中英

mock a non spring managed object while integration testing using mockMVC

I am writing integration test cases using MockMvc to test my REST API.

Within my implementation of the RESTAPI I am internally using RestTemplate(not directly from the controller but from within a util class which the controller calls) to call a 3rd party REST API. The RestTemplate which I use (to make the 3rd party rest API) is not a spring managed bean instead I am instantiating it as RestTemplate restTemplate = new RestTemplate();

I want to mock the restTemplate call(postForEntity).

I am trying the below approach:

My test class-

@ContextConfiguration(locations = {
    "classpath:test-applicationContext.xml"
})
@WebAppConfiguration

public class MockMVCTest {

  private MockMvc mockMvc;
  private RestTemplate restTemplate

  @Autowired
  private WebApplicationContext webApplicationContext;

  @Before
  public void setUp() {
    if (!initalized) {
     mockMvc =   MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
  restTemplate = (RestTemplate)webApplicationContext.getBean("restTemplate");

}

@Test
public void demo() throws Exception {
 when(
  restTemplate.postForEntity(
    eq("thirdpartyuri"),
    any(HttpEntity.class),
    eq(MyClass.class))).thenReturn(myresponse);

mockMvc.perform(
  post("uriExposedbyme")
    .contentType(MediaType.APPLICATION_JSON)
    .accept(MediaType.APPLICATION_JSON)
    .content(MY_PAYLOAD)).andExpect(status().isOk());
}

In my application-context I have the following mock defined:

<bean id="restTemplate" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="org.springframework.web.client.RestTemplate" />        </bean>

But when I execute my test case the RestTemplate is getting mocked but when a call to RestTemplate happens during the execution the actual resttemplate is called instead of my mock resttemplate.

Please suggest on how I can mock RestTemplate for my test case.

The util class instantiates its private RestTemplate, like you said: RestTemplate restTemplate = new RestTemplate();.

This means that it will use it, not the one mocked in the test. You can either make RestTemplate a spring managed bean in your actual code, or have a setter method on the util class and call this setter in the test using the mocked rest template.

Based on the information provided, I could say to try following changes and check whether it's resolved your issue. What I can see is since you autowire the WebApplicationContext as

@Autowired private WebApplicationContext webApplicationContext;

It might possible the development profile getting injected, rather test profile. Hence can you put this annotation to mark the class in Test profile at the top of the test class

@RunWith(SpringJUnit4ClassRunner.class) 

Still if you have issues, auto wire the rest template correctly with your RestTemplate instance as below.

@Autowired
@Qualifier("restTemplate")
private RestTemplate restTemplate;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM