Issue
How this code should be changed so that it does not throw below exception?
ArgumentCaptor<Date> argument = forClass(Date.class);
verify(ps, times(0)).setDate(anyInt(), argument.capture());
typeHandler.setNonNullParameter(ps, 1, "20170120", DATE);
assertEquals(new Date(2017, 01, 20), argument.getValue());
More code:
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.sql.*;
public class DateStringTypeHandler extends BaseTypeHandler<String> {
private static final DateTimeFormatter YYYY_MM_DD = DateTimeFormat.forPattern("yyyyMMdd");
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
LocalDate localDate = YYYY_MM_DD.parseLocalDate(parameter);
ps.setDate(i, new Date(localDate.toDateTimeAtStartOfDay().getMillis()));
}
}
@RunWith(MockitoJUnitRunner.class)
public class DateStringTypeHandlerTest {
@Mock
private PreparedStatement ps;
private DateStringTypeHandler typeHandler;
@Before
public void before() {
typeHandler = new DateStringTypeHandler();
}
@Test
public void testSetNonNullParameterPreparedStatementIntStringJdbcType() throws SQLException {
ArgumentCaptor<Date> argument = forClass(Date.class);
verify(ps, times(0)).setDate(anyInt(), argument.capture());
typeHandler.setNonNullParameter(ps, 1, "20170120", DATE);
assertEquals(new Date(2017, 01, 20), argument.getValue());
}
}
verify
throws exception:
org.mockito.exceptions.base.MockitoException:
No argument value was captured!
You might have forgotten to use argument.capture() in verify()...
...or you used capture() in stubbing but stubbed method was not called.
Be aware that it is recommended to use capture() only with verify()
Examples of correct argument capturing:
ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());
Solution
You should invoke the method of the class under test first. Then you verify using the captor:
@Test
public void testSetNonNullParameterPreparedStatementIntStringJdbcType() throws SQLException {
// Arrange
ArgumentCaptor<Date> argument = forClass(Date.class);
// Act
typeHandler.setNonNullParameter(ps, 1, "20170120", DATE);
// Assert
verify(ps).setDate(anyInt(), argument.capture());
assertEquals(new Date(2017, 01, 20), argument.getValue());
}
Also now you probably would not need the times(..)
argument.
Answered By - Maciej Kowalski
Answer Checked By - Timothy Miller (JavaFixing Admin)