How to unit test a cachable method

2019-08-30 06:56发布

I am using Spring Cache. I have a Spring controller and as part of the method responsible for that GET request, I have annotated it with @Cacheable(value = "customer", key = "#accountId"). In that method, it calls an API and does some business logic and then returns a DTO. With the cache annotation in place, I'm expecting on the first execution of this code will run normally but any subsequent calls later, it'll fetch the result from the cache.. that's correct right?

I'm writing a unit test to verify that the API was called once despite mocking multiple requests being sent to that controller. But the problem is that it keeps on calling the API multiple times and not calling the cache.

Unit test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebMvcTest(controllers = CustomerController.class, secure = false)
public class CustomerControllerTest {

private static final String ACCOUNT_ID = "1111";

   @MockBean
   private CustomerService customerService;
   @MockBean
   private CustomerPortAPI customerPortAPI;
   @Autowired
   MockMvc mockMvc;

   @Before
   public void setUp(){
      when(customerService.getStatus(any())).thenReturn("test");
      when(customerPortAPI.getAccount(any())).thenReturn(Account.builder().build());
   }
   @Test
public void shouldReturnCustomerDTOt() throws Exception {
  when(customerService.Status(any())).thenReturn("test");
  when(customerPortAPI.getAccount(ACCOUNT_ID)).thenReturn(Account.builder().accountId(ACCOUNT_ID).build());

  mockMvc.perform(get("/customer/{accountId}/status", ACCOUNT_ID)
     .accept(APPLICATION_JSON))
     .andExpect(status().isOk())
     .andExpect(jsonPath("status").value(customer.NOT_REQUIRED.name()));


  mockMvc.perform(get("/customer/{accountId}/status", ACCOUNT_ID)
     .accept(APPLICATION_JSON))
     .andExpect(status().isOk())
     .andExpect(jsonPath("status").value(customer.NOT_REQUIRED.name()));


  verify(customerPorAPI, times(1)).getAccount(ACCOUNT_ID);

}}

Controller Method:

@Cacheable(value = "statusEligibility", key = "#customerId")
@GetMapping
public CustomerStatusDTO getCustomerStatus(@PathVariable String customerId) {

Customer customer = cusomterPort.getAccount(customerId);
Status status = service.getStatus(customer);

if (status.equals(Cons.REQUIRED)) {
 /.../
} else {
 /.../
}

0条回答
登录 后发表回答