【发布时间】:2023-03-12 05:39:01
【问题描述】:
我正在使用 Spring-boot 测试(通过 JUnit4 和 Spring MockMvc)一个 REST 服务适配器。适配器只是将向它发出的请求传递给另一个 REST 服务(使用自定义 RestTemplate)并将附加数据附加到响应中。
我想运行 MockMvc 测试来执行控制器集成测试,但想用模拟覆盖控制器中的 RestTemplate 以允许我预定义第 3 方 REST 响应并防止它在每次测试。我已经能够通过实例化MockMvcBuilders.standAloneSetup() 并将其传递给控制器以使用post 中列出的注入的模拟进行测试(以及下面的设置)来完成此操作,但是我无法使用MockMvcBuilders.webAppContextSetup().
我浏览过其他几篇文章,但没有一篇回答关于如何实现这一点的问题。我想在测试中使用实际的 Spring 应用程序上下文而不是独立的,以防止在应用程序可能增长时出现任何空白。
编辑:我使用 Mockito 作为我的模拟框架,并试图将其中一个模拟注入到上下文中。如果这不是必需的,那就更好了。
控制器:
@RestController
@RequestMapping(Constants.REQUEST_MAPPING_PATH)
public class Controller{
@Autowired
private DataProvider dp;
@Autowired
private RestTemplate template;
@RequestMapping(value = Constants.REQUEST_MAPPING_RESOURCE, method = RequestMethod.GET)
public Response getResponse(
@RequestParam(required = true) String data,
@RequestParam(required = false, defaultValue = "80") String minScore
) throws Exception {
Response resp = new Response();
// Set the request params from the client request
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(Constants.PARAM_DATA, data);
parameters.put(Constants.PARAM_FORMAT, Constants.PARAMS_FORMAT.JSON);
resp = template.getForObject(Constants.RESTDATAPROVIDER_URL, Response.class, parameters);
if(resp.getError() == null){
resp.filterScoreLessThan(new BigDecimal(minScore));
new DataHandler(dp).populateData(resp.getData());
}
return resp;
}
}
测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = MainSpringBootAdapter.class)
@TestPropertySource("/application-junit.properties")
public class WacControllerTest {
private static String controllerURL = Constants.REQUEST_MAPPING_PATH + Constants.REQUEST_MAPPING_RESOURCE + compressedParams_all;
private static String compressedParams_all = "?data={data}&minScore={minScore}";
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@InjectMocks
private Controller Controller;
@Mock
private RestTemplate rt;
@Value("${file}")
private String file;
@Spy
private DataProvider dp;
@Before
public void setup() throws Exception {
dp = new DataProvider(file);
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void testGetResponse() throws Exception {
String[] strings = {"requestData", "100"};
Mockito.when(
rt.getForObject(Mockito.<String> any(), Mockito.<Class<Object>> any(), Mockito.<Map<String, ?>> any()))
.thenReturn(populateTestResponse());
mockMvc.perform(get(controllerURL, strings)
.accept(Constants.APPLICATION_JSON_UTF8))
.andDo(MockMvcResultHandlers.print());
Mockito.verify(rt, Mockito.times(1)).getForObject(Mockito.<String> any(), Mockito.<Class<?>> any(), Mockito.<Map<String, ?>> any());
}
private Response populateTestResponse() {
Response resp = new Response();
resp.setScore(new BigDecimal(100));
resp.setData("Some Data");
return resp;
}
}
【问题讨论】:
标签: java spring-boot mockito integration-testing junit4