Метод контроллера, который я тестирую
@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;
}
модульный тест
@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());
}
Этот тест еще раз завершен, даже не истекает время ожидания в моей IDE, я должен его убитькаждый раз, когда я запускаю его, если запустить все приложение, эта конечная точка /customers
выдает 404, когда в приложение не добавлено ни одного клиента.
Что мне нужно сделать, чтобы этот тест завершился, CustomerService
в конечном счете, call вызывает CustomerRepository
, над которым я издевался, потому что не мог понять, как смоделировать метод асинхронного вызова к сервису.класс обслуживания клиентов выглядит следующим образом:
@Async
@Service
public class CustomerAsyncService {
private CustomerRepository customerRepository;
@Autowired
public CustomerAsyncService(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE)
public ListenableFuture<Page<Customer>> findAll(Pageable pageable) {
return AsyncResult.forValue(customerRepository.findAll(pageable));
}
Я надеялся, что насмешка над методом Repository поможет.Как мне посмеяться над вызовом асинхронной службы