当模拟的NullPointerException调用时,我看到的行为是第二个测试中的一个restTemplate。这指出了一个问题,在重置模拟。令我惊讶的是修复(使两个测试都通过了)。
将代码从@MockBean private RestTemplate restTemplate;修改为@MockBean(reset = MockReset.NONE) private RestTemplate restTemplate;解决了这个问题。这里有几个问题:
希望我已经提供了足够的上下文来回答这个问题。
我已经创建了一个我所看到的简单示例:测试配置:
@Profile("test")
@Configuration
public class TestConfiguration {
@Bean
@Primary
public ObjectNode getWeatherService(RestTemplate restTemplate) {
return new WeatherServiceImpl(restTemplate);
}
}测试:
@SpringBootTest
@ActiveProfiles("test")
@AutoConfigureMockMvc
class SamTest {
@Autowired private MockMvc mockMvc;
@MockBean private RestTemplate restTemplate;
/*
Works:
@MockBean(reset = MockReset.NONE) private RestTemplate restTemplate;
Fails:
@MockBean(reset = MockReset.BEFORE) private RestTemplate restTemplate;
@MockBean(reset = MockReset.AFTER) private RestTemplate restTemplate;
*/
@Test
public void testOne() throws Exception {
Mockito.when(restTemplate.getForEntity("http://some.weather.api", ObjectNode.class))
.thenReturn(new ResponseEntity("{\"weather\" : \"rainy\"}", HttpStatus.OK));
// Makes call to standard @RestController with a @GetMapping
// Call to external API is contained in @Service class.
// Currently controller just passes through the json from the underlying service call.
this.mockMvc.perform(
get("/weather/check").
contentType(MediaType.APPLICATION_JSON_VALUE)).
andExpect(status().isOk());
}
@Test
public void testTwo() throws Exception {
Mockito.when(restTemplate.getForEntity("http://some.weather.api", ObjectNode.class))
.thenReturn(new ResponseEntity("{\"error\" : \"bandwidth\"}", HttpStatus.BANDWIDTH_LIMIT_EXCEEDED));
this.mockMvc.perform(
get("/weather/check").
contentType(MediaType.APPLICATION_JSON_VALUE)).
andExpect(status().is5xxServerError());
}
}服务:
@Service
public class WeatherServiceImpl implements WeatherService {
private final RestTemplate restTemplate;
@Autowired
public WeatherServiceImpl(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public ObjectNode retrieve(URI uri) {
ResponseEntity<ObjectNode> response = restTemplate.getForEntity(uri, ObjectNode.class);
return response.getBody();
}
}发布于 2021-09-24 16:26:08
对于@MockBean的默认行为存在误解:
为什么MockReset.RESET的默认@MockBean行为不起作用?我设置测试的方式有问题吗?默认的MockReset.RESET失败了吗?
来自MockBean.reset方法文档:
重置模式以应用于模拟bean。默认情况是MockReset.AFTER,这意味着在调用每个测试方法之后,将自动重置模拟。
因此,在执行第一个测试案例之后,您的MockBean将被重置并从应用程序上下文中取消注册,然后您的第二个测试案例将发现它为null,而在@MockBean(reset = MockReset.NONE)情况下不会像您所做的那样发生这种情况。
https://stackoverflow.com/questions/69306972
复制相似问题