简体   繁体   中英

Mock object is not getting injected in Service Class when Cucumber is used with Mockito

We are calling a third party service which I would like to mock and not call it. For Some reason, the mock RestTemplate doesn't get injected and the class has real "RestTemplate" object.

My cucumber class look like this

@RunWith(Cucumber.class)
@CucumberOptions(plugin = { "pretty", "html:build/cucumber",
    "junit:build/cucumber/junit-report.xml" }, 
    features = "src/test/resources/feature", 
    tags = { "@FunctionalTest","@In-Progress", "~@TO-DO" },
    glue= "com.arrow.myarrow.service.order.bdd.stepDef")
    public class CucumberTest {
     }

and the StepDefinition looks like this

@ContextConfiguration(loader = SpringBootContextLoader.class, classes = 
OrderServiceBoot.class)
@WebAppConfiguration
@SpringBootTest
public class BaseStepDefinition {


@Autowired
WebApplicationContext context;

MockMvc mockMvc;

@Rule public MockitoRule rule = MockitoJUnit.rule();

 RestTemplate restTemplate = mock(RestTemplate.class);

@Before
public void setup() {
    mockMvc = MockMvcBuilders.webAppContextSetup(context).build();

    //Telling rest template what to do 
    when(restTemplate.exchange(Mockito.anyString(), Mockito.
    <HttpMethod>any(), Mockito.<HttpEntity<?>>any(), Mockito.
    <Class<UserProfile>>any()))
            .thenReturn(new ResponseEntity<>(userProfile, 
    HttpStatus.OK));

}

This is my service class looks like

@Autowired
RestTemplate restTemplate;

public UserProfile getUserProfile(OAuth2Authentication auth){

ResponseEntity<UserProfile> response 
  =restTemplate.exchange("http://localhost:8084/api/v1.0/user/profile", HttpMethod.GET,new HttpEntity<>(new HttpHeaders()),UserProfile.class);
   return response.getBody();
   }

In the service class, the RestTemplate restTemplate is not mocked, it contains the real object so it is trying to call the real service which is not intended.

Does anyone knows why Mocking isn't working here?

The way it worked for me is by creating a class in TestFolder and then defining a new bean for resttemplate which generates the MockRestTemplate instance.

@Configuration
@Profile("local")
public class CucumberMockConfig {

@Bean
@Primary
public RestTemplate getRestRemplate() {     
    return  mock(RestTemplate.class);
  }
}

In test class use (Dont use @Mock or Mock(restTemplate), as you don't want a new object)

@Autowired
RestTemplate restTemplate


@Before
public void setup() throws JsonProcessingException {

    UserProfile userProfile = new UserProfile();
    userProfile.setCompany("myCompany");

    when(restTemplate.exchange(Mockito.endsWith("/profile"),
            Mockito.<HttpMethod>eq(HttpMethod.GET),
            Mockito.<HttpEntity<?>>any(),
            Mockito.eq(UserProfile.class)))
            .thenReturn(ResponseEntity.ok().body(userProfile));
}

and in service/config class use

 @Autowired
 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