I am trying to write test for the function, rollDays
. However, I am getting InvalidUseOfMatchersException
.
rollDays
is inside CalculateDateService
:
public class CalculateDateService {
LocalDate rollDays(int days, LocalDate date, String mar) {
int dir = days > 0 ? 1 : -1;
for(int numOfDays = Math.abs(days); closed(date, mar) || numOfDays-- > 0; date = date.plusDays((long) dir)) {
}
return date;
}
Boolean closed(LocalDate date, String mar) {
return this.nonSettle(date);
}
Boolean nonSettle(LocalDate date) {
int year = LocalDate.now().getYear();
LocalDate dayBeforeChristmas = LocalDate.of(year, 12, 24);
LocalDate dayBeforenewYear = LocalDate.of(year, 12, 31);
return (date.isEqual(dayBeforeChristmas) || date.isEqual(dayBeforenewYear));
}
}
The test:
@InjectMocks
private CalculateDateService tested;
@Test
public void testRollDays() {
Mockito.when(tested.nonSettle(Mockito.any(LocalDate.class))).thenReturn(Boolean.FALSE);
Mockito.when(tested.nonSettle (LocalDate.of(2021,12,24))).thenReturn(Boolean.TRUE);
LocalDate result = tested.rollDays(2, LocalDate.of(2021, 12, 22));
LocalDate correctRolledDate = LocalDate.of(2021, 12, 25);
assertEquals(result, correctRolledDate);
}
The error I got is:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
and something along the line of “expected matcher 0, but got 1”
I tried updating the test part to be
Mockito.when(tested.nonSettle(LocalDate.of(2022,12,22))).thenReturn(Boolean.FALSE);
Mockito.when(tested.nonSettle(LocalDate.of(2022,12,23))).thenReturn(Boolean.FALSE);
Mockito.when(tested.nonSettle(LocalDate.of(2022,12,25))).thenReturn(Boolean.FALSE);
Mockito.when(tested.nonSettle(LocalDate.of(2022,12,24))).thenReturn(Boolean.TRUE);
to avoid using matcher
but I got NullPointerException
instead which happened for the line within nonSettle
LocalDate dayBeforeChristmas = LocalDate.of(year, 12, 24);
Any help will be greatly appreciated, thank you in advance.
CodePudding user response:
Your example still has errors, but i managed to correct it. Your issue is with
Mockito.when(something.isCalled()).thenReturn(something);
something
needs to be a mock, in your case, it's not, tested is an instance of CalculateDateService
. You can read more about @Mock and @InjectMocks here.
So, you just have to comment/remove your Mockito.when()
statements, and everything will work. For example, this works:
package com.example;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.LocalDate;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class CalculateDateServiceTest {
@InjectMocks
private CalculateDateService tested;
@Test
void testRollDays() {
LocalDate result = tested.rollDays(2, LocalDate.of(2021, 12, 22));
LocalDate correctRolledDate = LocalDate.of(2021, 12, 24);
assertEquals(result, correctRolledDate);
}
}
Unit Test:
package com.example;
import java.time.LocalDate;
public class CalculateDateService {
LocalDate rollDays(int days, LocalDate date) {
int dir = days > 0 ? 1 : -1;
for(int numOfDays = Math.abs(days); closed(date) || numOfDays-- > 0; date = date.plusDays((long) dir)) {
}
return date;
}
Boolean closed(LocalDate date) {
return this.nonSettle(date);
}
Boolean nonSettle(LocalDate date) {
int year = LocalDate.now().getYear();
LocalDate dayBeforeChristmas = LocalDate.of(year, 12, 24);
LocalDate dayBeforenewYear = LocalDate.of(year, 12, 31);
return (date.isEqual(dayBeforeChristmas) || date.isEqual(dayBeforenewYear));
}
}
Also, the @InjectMocks
is not required, as there are no mocks to inject. You can just use CalculateDateService tested = new CalculateDateService();
in your test method.
By the way, your for loop(although it works) and your method name are confusing. You might want to review/rewrite those.