我正在尝试测试数据库为空/数据库未返回任何内容的情况。
我用Mockito编写了一个junit4测试类。由嘲讽创建一个服务类和dao类。首先,我定义了“ when”方法,并且它起作用了。后来,我尝试拉出“ when”方法调用,看看会发生什么,无论如何它都起作用。为什么?
当调用myService.getDistinctObjectList()时,类myService将调用myDao的所有四个方法。所以我认为我必须模拟所有四种方法并返回虚拟结果。如果未配置myDao.someMethod()时会发生什么情况? MyDao应该与数据库一起使用,但是我什么也没做。
我附上了MyDao和MyService的示例代码以供参考。 (我简化了它们,MyDao有四种方法可以检索四种对象)
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;
}
}
这是Test类:
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());
}
答案 0 :(得分:3)
除非您显式更改模拟的默认行为,否则它将返回"nice values"。对于集合,默认的返回值是一个空集合,因此您不需要像注释掉的代码那样显式地使用when
调用来返回此类空集合。
答案 1 :(得分:1)
如果未调用myDao.someMethod()会发生什么情况 配置?
使用普通的模仿(因此,无需使用间谍方法调用read方法),它将不会引发任何异常或错误,它将仅将该方法实现为空主体。然后,如果该方法声明为void
,则不需要其他行为,并且如果该方法声明为带有返回类型,则它返回已声明类型结果的默认值,该默认值是对象的null
引用,但用于Mockito返回它们的空实例以及最原始的默认值的集合。
但是请注意,通常Mockito的此功能不会对您的测试逻辑造成任何副作用,因为通常您需要声明列表的内容,而不仅是声明它们的非无效性。
但是在您的情况下,您将模拟空列表:
when(myDao.listSomeObjectTypeB()).thenReturn( Collections.<SomeObjectTypeB>emptyList() );