Reputation: 3742
I am trying to test a scenario with empty database/ nothing returned from database.
I wrote a junit4 test class with mockito. There is a service class and dao class created by mockito. At first, I defined the "when" method and it worked. Later, I tried to pull the "when" method calls and see what would happen, it worked anyway. Why?
The class myService would call all four methods of myDao when myService.getDistinctObjectList() is called. So I thought I have to mock all four methods and return dummy result. What would happen if myDao.someMethod() is called when it is not configured? MyDao is supposed to work with a database but I didn't give anything to it.
I attached the sample code of MyDao and MyService for reference. ( I simplified them, MyDao has four methods which retrieve four kinds of object)
public class MyDaoImpl implements MyDao {
@SuppressWarnings("unused")
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
private String schema;
@ConstructorProperties({ "dataSource", "schema" })
private MyDaoImpl(DataSource dataSource, String schema) {
this.dataSource = dataSource;
this.schema = schema;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public List<SomeObjectTypeA> listSomeObjectTypeA() {
return this.jdbcTemplate.query("select * from " + schema + ".SOME_TABLE", new RowMapper<SomeObjectTypeA>() {
@Override
public SoftBillAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
String memberA = rs.getString("MEMBER_A");
String memberB = rs.getString("MEMBER_B");
}
});
}
public List<SomeObjectTypeA> listSomeObjectTypeB() {
//omitted
}
public List<SomeObjectTypeA> listSomeObjectTypeC() {
//omitted
}
public List<SomeObjectTypeA> listSomeObjectTypeD() {
//omitted
}
}
public class MyServiceImpl implements MyService {
private MyDao myDao;
public MyServiceImpl(){}
@ConstructorProperties({ "myDao" })
public MyServiceImpl(MyDao myDao) {
this.myDao = myDao;
}
@Override
public List<String> getSomeObjectTypeA_MemberA_Only() {
List<SomeObjectTypeA> list = myDao.listSomeObjectTypeA();
List<String> memberAList = new ArrayList<String>();
for (SomeObjectTypeA objectA : list) {
memberAList.add(objectA.getMemberA());
}
return memberAList;
}
}
public class MyServiceImpl implements MyService {
private MyDao myDao;
public MyServiceImpl(){}
@ConstructorProperties({ "myDao" })
public MyServiceImpl(MyDao myDao) {
this.myDao = myDao;
}
@Override
public List<String> getSomeObjectTypeA_MemberA_Only() {
List<SomeObjectTypeA> list = mydao.listSomeObjectTypeA();
List<String> memberAList = new ArrayList<String>();
for (SomeObjectTypeA objectA : list) {
memberAList.add(objectA.getMemberA());
}
return memberAList;
}
}
This is the Test class:
public class Test1{
@InjectMocks
private MyServiceImpl myService;
@Mock
private MyDao myDao;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testEmptyDatabase() {
//ArrayList<SomeObjectTypeA> list = new ArrayList<SomeObjectTypeA>();
//list.add( new SomeObjectTypeA("A","A", "A", "A") );
//when(myDao.listSomeObjectTypeA()).thenReturn( Collections.<SomeObjectTypeA>emptyList() );
//when(myDao.listSomeObjectTypeB()).thenReturn( Collections.<SomeObjectTypeB>emptyList() );
//when(myDao.listSomeObjectTypeC()).thenReturn( Collections.<SomeObjectTypeC>emptyList() );
//when(myDao.listSomeObjectTypeD()).thenReturn( Collections.<SomeObjectTypeD>emptyList() );
List<String> distinctList = myService.getDistinctObjectList(); // myService.getDistinctObjectList() end up calling all four methods of myDao
//Write the List to a file, with a trailer with record count
OutputWriter outputWriter = new OutputWriterImpl(outputFileDir, outputFilePrefix,outputFileSuffix);
try{
outputWriter.writeOutput(distinctList);
}catch(IOException e){
e.printStackTrace();
}
//Create a control file for comparison
try{
BufferedWriter bfr = new BufferedWriter(new FileWriter(compareFileDir+compareFilePrefix+compareFileSuffix));
bfr.write("Trailer|");
bfr.write(String.format("%07d", 0));
bfr.newLine();
bfr.close();
}catch(IOException e){
e.printStackTrace();
}
File file1 = new File(outputFileDir + outputFilePrefix + date + outputFileSuffix);
File file2 = new File(compareFileDir+ compareFilePrefix+compareFileSuffix);
System.out.println(file1.length()); // show 17
System.out.println(file2.length()); // show 17
assertEquals(file1.length(), file2.length());
}
Upvotes: 1
Views: 379
Reputation: 131506
What would happen if myDao.someMethod() is called when it is not configure?
With plain mockito (so without spy usage that call the read method), it will not throw any exception or error, it will simply implement the method as an empty body. Then if the method is declared as void
, no additional behavior is required and if the method is declared with a return type, it returns the default value of the declared type result that is null
reference for objects but for collections where Mockito returns an empty instance of them and at last default values for primitives.
But note that generally this feature of Mockito doesn't cause any side effect in your test logic as generally you want to assert the content of the Lists and not only their non nullity.
But in your case you mock empty Lists :
when(myDao.listSomeObjectTypeB()).thenReturn( Collections.<SomeObjectTypeB>emptyList() );
Upvotes: 1
Reputation: 312169
Unless you explicitly change the mock's default behavior, it will return "nice values". For collection, the default return value is an empty collection, so you don't need to explicitly use a when
call to return such empty collections as your commented out code does.
Upvotes: 3