I'm struggling on testing my endpoint when I set a specific date.
I don't want to use PowerMock to mock a static method instead I decided to change the implementation of my service and use the LocalDate.now(Clock clock) implementation in the way to be easier to test it.
I added to my SpringBootApplication class:
@Bean
public Clock clock() {
return Clock.systemDefaultZone();
}
and autowired it to my Service
@Autowired
private Clock clock;
and used it in my implementation as that:
LocalDateTime localDate = LocalDateTime.now(clock);
On the test side I mocked the Clock
private final static LocalDate WEEKEND = LocalDate.of(2020, 07, 05);
@Mock
private Clock clock;
private Clock fixedClock;
and used it as that:
MockitoAnnotations.initMocks(this);
//tell your tests to return the specified LOCAL_DATE when calling LocalDate.now(clock)
fixedClock = Clock.fixed(WEEKEND.atTime(9, 5).toInstant(ZoneOffset.UTC), ZoneId.of("CET"));
doReturn(fixedClock.instant()).when(clock).instant();
doReturn(fixedClock.getZone()).when(clock).getZone();
ResponseEntity<String> response = restTemplate.postForEntity(base.toString(), request, String.class);
When I debuged it, the fixedClock
has the value which I expected FixedClock[2020-07-05T09:05:00Z,CET]
. Instead if I put a breakpoint on the service implementantion, the localDate
variable has the value 2020-07-09
- the .now()
.
My issue is that: why the localDate
variable hasn't the value of fixedClock
variable?
Thank you very much for your time!
Later edit:
Here is the constructor of the Service:
@Autowired
public SavingAccountService(
SavingAccountRepository savingAccountRepository, UserRepository userRepository, Clock clock) {
this.savingAccountRepository = savingAccountRepository;
this.userRepository = userRepository;
this.clock = clock;
}
The annotations on my TestClass:
RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = ChallengeApplication.class)
@ActiveProfiles("test")
public class SavingAccountTest {
@Mock
private Clock clock;
private Clock fixedClock;
@InjectMocks
private SavingAccountService savingAccountService;
@Autowired
private TestRestTemplate restTemplate;
private URL base;
@LocalServerPort
int port;
I want also to mention that from my test I'm calling the Controller and not the Service.
private final SavingAccountService savingAccountService;
public SavingAccountRestController(SavingAccountService savingAccountService) {
this.savingAccountService = savingAccountService;
}
@Override
@PostMapping
public ResponseEntity<?> newSavingAccount(@RequestBody SavingAccount savingAccount) {
EntityModel<SavingAccount> newSavingAccount = savingAccountService.newSavingAccount(savingAccount);
return new ResponseEntity<>(newSavingAccount, HttpStatus.CREATED);
}