Spring 如何测试具有外部客户端的my 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

我有一个使用2个fein客户端的rest控制器,我想用不同的示例编写和测试rest控制器,我不是编写springboot测试的专家

在这个场景中,我没有要测试的存储库,只是通过rest控制器访问假客户机。下面是我的测试控制器代码

@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;iheaders.putheader,新的ArrayListvalues; 返回标题; } 专用静态响应convertResponseRequest请求,MockHttpServletResponse响应{ 返回响应.builder .请求 .statusresp.getStatus .bodyresp.getContentAsByteArray .HeaderResp.getHeaderNames.stream .collectCollectors.toMapidentity,resp::getHeaders 建筑 } } 并使用它创建您的外国客户:

返回外国建筑商 .clientnew MockMvcFeignClientmockMvc ...
因此,对于可以进行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())
    }

}