单元测试异步延迟结果控制器被永久挂起

时间:2018-12-07 15:47:25

标签: unit-testing spring-mvc spring-boot spring-data-jpa spring-boot-test

我正在测试的控制器方法

!!react 5

单元测试

@GetMapping("/customers")
@ResponseBody
public DeferredResult<ResponseEntity<Resources<Resource<Customer>>>> getAllCustomers(
        @PageableDefault(page = 0, size = 20) @SortDefault.SortDefaults({
                @SortDefault(sort = "name", direction = Direction.ASC) }) Pageable pageable,
        PagedResourcesAssembler<Customer> assembler, HttpServletRequest request) {

    DeferredResult<ResponseEntity<Resources<Resource<Customer>>>> response = new DeferredResult<>(
            Long.valueOf(1000000));
    response.onTimeout(() -> response
            .setErrorResult(ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body("Request timed out.")));
    response.onError((Throwable t) -> {
        response.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occured."));
    });

    ListenableFuture<Page<Customer>> future = customerService.findAll(pageable);

    future.addCallback(new ListenableFutureCallback<Page<Customer>>() {

        @Override
        public void onSuccess(Page<Customer> result) {
            Link self = new Link(
                    ServletUriComponentsBuilder.fromRequestUri(request).buildAndExpand().toUri().toString(),
                    "self");
            LOGGER.debug("Generated Self Link {} for Customer Resource Collection", self.getHref());
            if (result.hasContent())
                response.setResult(
                        ResponseEntity.ok(assembler.toResource(result, customerResourceAssembler, self)));
            else
                response.setErrorResult(ResponseEntity.notFound());
            LOGGER.debug("Returning Response with {} customers", result.getNumber());
        }

        @Override
        public void onFailure(Throwable ex) {
            LOGGER.error("Could not retrieve customers due to error", ex);
            response.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Could not save customers list due to server error."));
        }

    });

    return response;
}

该测试完成了,甚至没有在我的IDE上超时,我必须在每次运行它时都将其杀死,如果运行整个应用程序,则此@RunWith(SpringRunner.class) @WebMvcTest(CustomerController.class) @EnableSpringDataWebSupport @Import({ CustomerResourceAssember.class, BranchResourceAssembler.class, InvoiceResourceAssembler.class, CustomerAsyncService.class }) public class CustomerControllerTests { @Autowired private MockMvc mockMvc; @Autowired CustomerAsyncService customerService; @MockBean private CustomerRepository customerRepository; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void testWhenNoCustomersThenReturnsEmptyHALDocument() throws Exception { // Given BDDMockito.given(customerRepository.findAll(PageRequest.of(0, 20))) .willReturn(new PageImpl<Customer>(Collections.emptyList())); // When MvcResult result = mockMvc.perform(get("/customers").accept(MediaTypes.HAL_JSON_VALUE)).andDo(print()) .andExpect(request().asyncStarted()) .andExpect(request().asyncResult(new PageImpl<Customer>(Collections.emptyList()))).andReturn(); // Then mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk()); } 端点在没有添加任何客户时给出404到应用程序。

我需要做些什么来确保此测试完成,/customers调用最终会调用我嘲笑的CustomerService,因为我无法理解如何模拟异步服务调用方法。客户服务类别如下

CustomerRepository

我希望模拟Repository方法可以解决问题。如何模拟异步服务调用

1 个答案:

答案 0 :(得分:0)

我的坏处是错误地使用了模拟,这可行

@RunWith(SpringRunner.class)
@WebMvcTest(CustomerController.class)
@Import({ CustomerResourceAssember.class, BranchResourceAssembler.class, InvoiceResourceAssembler.class,
        CustomerAsyncService.class })
public class CustomerControllerTests {

    @MockBean
    private CustomerRepository customerRepository;

    @InjectMocks
    CustomerAsyncService customerService = new CustomerAsyncService(customerRepository);

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        JacksonTester.initFields(this, objectMapper);
    }

    @Test
    public void testReturnsNotFoundForEmptyGetAllCustomersResult() throws Exception {

        // Given
        Page<Customer> emptyPage = new PageImpl<Customer>(Collections.emptyList());
        BDDMockito.given(customerRepository.findAll(any(Pageable.class))).willReturn(emptyPage);

        // When
        MvcResult result = mockMvc.perform(get("/customers")).andExpect(request().asyncStarted()).andDo(print()).andReturn();

        // Then
        mockMvc.perform(asyncDispatch(result)).andDo(print()).andExpect(status().isNotFound());
    }


}