Spring 如何测试具有外部客户端的my rest控制器?
我有一个使用2个fein客户端的rest控制器,我想用不同的示例编写和测试rest控制器,我不是编写springboot测试的专家 在这个场景中,我没有要测试的存储库,只是通过rest控制器访问假客户机。下面是我的测试控制器代码Spring 如何测试具有外部客户端的my rest控制器?,spring,spring-boot,spring-boot-test,spring-cloud-feign,netflix-feign,Spring,Spring Boot,Spring Boot Test,Spring Cloud Feign,Netflix Feign,我有一个使用2个fein客户端的rest控制器,我想用不同的示例编写和测试rest控制器,我不是编写springboot测试的专家 在这个场景中,我没有要测试的存储库,只是通过rest控制器访问假客户机。下面是我的测试控制器代码 @RestController public class CustomerController { @Autowired private CustomerClient customerClient; @Autowired privat
@RestController
public class CustomerController {
@Autowired
private CustomerClient customerClient;
@Autowired
private PaymentsClient paymentsClient;
@RequestMapping(path = "/getAllCustomers", method = RequestMethod.GET)
public ResponseEntity<Object> getAllCustomers() {
List<Customer> customers = customerClient.getAllCustomers();
return new ResponseEntity<>(customers, HttpStatus.OK);
}
@RequestMapping(path = "/{customerId}", method = RequestMethod.GET)
public ResponseEntity<Object> get(@PathVariable() long customerId) {
try {
Customer c = customerClient.getCustomerById(customerId);
if (c != null) {
return new ResponseEntity<>(c, HttpStatus.OK);
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Customer Not Found");
}
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
@RequestMapping(path = "/{customerId}", method = RequestMethod.PATCH)
public ResponseEntity<Object> UpdateCustomer(@PathVariable() Long customerId, @RequestBody Customer customer) {
Customer c;
try {
c = customerClient.update(customerId, customer);
if (c != null) {
return new ResponseEntity<>(c, HttpStatus.OK);
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Customer Not Found");
}
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
@RequestMapping(path = "", method = RequestMethod.POST)
public ResponseEntity<Object> saveCustomer(@RequestBody Customer customer) {
Customer c;
try {
c = customerClient.saveCustomer(customer);
return new ResponseEntity<>(c, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
@RequestMapping(path = "/registerPayment", method = RequestMethod.POST)
public ResponseEntity<Object> saveCustomer(@RequestBody Payment payment) {
Payment p = null;
Customer c = null;
try {
c = customerClient.getCustomerById(payment.getCustomerId());
p = paymentsClient.saveCustomer(payment);
return new ResponseEntity<>(p, HttpStatus.OK);
} catch (Exception e) {
if (null == c) {
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body("Customer Does not Exist");
} else {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
}
我得到下面的错误
NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc' available: expected at least 1 bean which qualifies as autowire candidate.
它和编写任何其他JUnit测试一样简单
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class CustomerControllerTest {
@Mock
private CustomerClient customerClient;
@InjectMocks
private CustomerController customerController;
@Test
public void getAllCustomers() {
List<Customer> customers = new ArrayList<>();
customers.add(new Customers("name"));
Mockito.when(customerClient.getAllCustomers()).thenReturn(customers);
Mockito.assertEquals(customers.toString(),customerController.getAllCustomers())
}
}
您需要自己的可在MockMvc之外工作的外部客户端:
导入静态java.nio.charset.StandardCharsets.UTF_8;
导入静态java.util.function.function.identity;
导入静态org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request;
进口国外客户;
进口外国请求;
进口国外反应;
导入java.io.UncheckedIOException;
导入java.io.UnsupportedEncodingException;
导入java.net.URI;
导入java.net.url解码器;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.stream.collector;
导入org.springframework.http.HttpHeaders;
导入org.springframework.http.HttpMethod;
导入org.springframework.mock.web.MockHttpServletResponse;
导入org.springframework.test.web.servlet.MockMvc;
导入org.springframework.test.web.servlet.ResultActions;
导入org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
公共类MockMvcFeignClient实现客户端{
私有最终MockMvc MockMvc;
公共MockMvcFeignClientMockMvc mockMvc{
this.mockMvc=mockMvc;
}
@凌驾
公共响应executeRequest请求,请求.选项{
URI requestUrl=URI.createrequest.url;
List uriVars=新阵列列表;
字符串urlTemplate=FillVarsandGetUrlTemplaterRequestUrl,uriVars;
HttpMethod=HttpMethod.valueOfrequest.method;
字节[]body=request.body;
HttpHeaders HttpHeaders=convertHeadersrequest;
MockHttpServletRequestBuilder requestBuilder=requestmethod,urlTemplate,uriVars.toArray
.校长
.内容体;
mockhttpservletresp;
试一试{
ResultActions ResultActions=mockMvc.performrequestBuilder;
resp=resultActions.andReturn
.getResponse;
}捕获异常e{
在执行请求时抛出新的IllegalStateExceptionError,e;
}
返回ConverterResponseRequest,resp;
}
静态字符串fillVarsAndGetUrlTemplateURI请求URL,列表Urivar{
StringBuilder urlTemplate=新建StringBuilderrequestUrl.getPath;
如果requestUrl.getQuery!=null{
urlTemplate.append'?';
String[]pairs=requestUrl.getRawQuery.split&;
对于int i=0;i因此,对于可以进行MockMvc集成测试的测试,现在您可以通过假客户端调用它。我认为您需要另外添加@AutoConfigureMockMvc来配置MockMvc。原始问题使用MockMvc,而不是直接调用控制器!
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class CustomerControllerTest {
@Mock
private CustomerClient customerClient;
@InjectMocks
private CustomerController customerController;
@Test
public void getAllCustomers() {
List<Customer> customers = new ArrayList<>();
customers.add(new Customers("name"));
Mockito.when(customerClient.getAllCustomers()).thenReturn(customers);
Mockito.assertEquals(customers.toString(),customerController.getAllCustomers())
}
}