【问题标题】:Spring WebTestClient bindToController usageSpring WebTestClient bindToController 用法
【发布时间】:2019-03-11 04:57:22
【问题描述】:

我正在尝试弄清楚如何使用 WebTestClient.bindToController()。

我有以下两个课程:

  • 控制器
  • 服务

Controller.methodx() 调用 Service.methody()。 Service.methody() 调用外部 REST POST 端点。

如何使用 WebTestClient.bindToController() 来测试这个控制器?我在网上找不到很多使用信息。

控制器:

@RestController
@RequestMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class CustomerController {

@Autowired
private CustomerService customerService;


@PostMapping(value="/customer", consumes= MediaType.APPLICATION_JSON_UTF8_VALUE)
public Mono<Customer> saveCustomer(@RequestBody Customer customer){
    return this.customerService.saveCustomer(customer);
}

服务:

@Service
public class CustomerService implements ICustomerService {


@Autowired  
private WebClient webClient;      


@Override
public Mono<Customer> storeMessage(Customer cust) {

     Mono<Customer> resp = this.webClient.post() 
              .uri("/postdata")
              .body(BodyInserters.fromObject(customer))
              .exchange();

    return resp
}

}

配置:

@Configuration
public class ProdConfig {


@Bean
public ICustomerService getCustomerService() {
    return new CustomerService();
}

@Bean
public WebClient getWebClient() {

    return WebClient.builder()
              .baseUrl("baseurl")
              .defaultHeader(HttpHeaders.CONTENT_TYPE, MIME_TYPE)
              .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
              .build();
}

}

测试类:

@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = TestConfig.class)
@AutoConfigureMockMvc

public class CustomerControllerTest {

 @MockBean
 private CustomerService customerservice;

 private WebTestClient testClient;

 @Test
 public void testSaveCustomer() throws Exception {       
    testClient= WebTestClient.bindToController(new CustomerController(customerService)).build();

    testClient.post().uri("/customer").body(BodyInserters.fromObject(customer))
            .exchange()
            .expectStatus().is2xxSuccessful();
 }
}

测试配置:

@Profile("test")
@Configuration
@EnableAutoConfiguration
public class TestConfig {


@Bean
public WebClient getWebClient() {
    return WebClient.builder()
              .baseUrl("baseurl")
              .defaultHeader(HttpHeaders.CONTENT_TYPE, MIME_TYPE)
              .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
              .build();
}

}

运行测试类时出错:

org.springframework.test.context.TestContextManager[0;39m: Caught exception while invoking 'afterTestMethod' callback on 
TestExecutionListener [org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@61df66b6] for test method 
[public void CustomerControllerTest.testSaveCustomer()] and test instance 
[CustomerControllerTest@22da200e]
java.lang.NoSuchMethodError: org.mockito.MockingDetails.getMockCreationSettings()Lorg/mockito/mock/MockCreationSettings;
    at org.springframework.boot.test.mock.mockito.MockReset.get(MockReset.java:107)

【问题讨论】:

    标签: spring unit-testing webclient


    【解决方案1】:

    WebTestClient 在内部使用 WebClient 来执行请求。 我们可以简单地将控制器绑定到 WebTestClient 来处理请求映射,而不是提供基本 url 来发出请求。

    CustomerController.java

    @RestController
    @RequestMapping(produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public class CustomerController {
    
        private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    
        private CustomerService customerService;
    
        public CustomerController( CustomerService customerService) {
            this.customerService = customerService;
        }
    
        @PostMapping(value="/customer", consumes= MediaType.APPLICATION_JSON_UTF8_VALUE)
        public Mono<Customer> saveCustomer(@RequestBody Customer customer){
            return this.customerService.saveCustomer(customer);
        }
    

    CustomerControllerTest.java

    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class CustomerControllerRestTest {
    
    
        private WebTestClient testClient;
    
        @MockBean
        private CustomerService customerService;
    
    
        @Before
        public void setup() {
            //mock service here
        }
    
    
    
        @Test
        public void  testSaveCustomer() throws Exception {
    
            Customer customer = new Customer(1L, "test", CustomerGender.MALE);
            testClient= WebTestClient.bindToController(new CustomerController(customerService)).build();
    
            testClient.post().uri("/customer").body(BodyInserters.fromObject(customer))
                    .exchange()
                    .expectStatus().is2xxSuccessful();
    
    
        }
    
    }
    

    【讨论】:

    • 我的对象依赖项与您的示例略有不同。当我像你建议的那样设置我的测试类时,我得到了一个错误。我将编辑我的帖子以添加详细信息。
    • 问题在于你的依赖,使用spring boot 2.x.x。
    • 我的spring boot版本是2.1.2.RELEASE。
    • 这是因为类路径依赖问题。检查你的 pom
    猜你喜欢
    • 2020-08-26
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多