java - 为什么在不定义 "when"方法的情况下使用 Mockito 进行 JUnit 测试?

标签 java junit mockito

我正在尝试测试一个数据库为空/数据库没有返回任何内容的场景。

我用 mockito 写了一个 junit4 测试类。 mockito 创建了一个服务类和 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;
    }
}

这是测试类:

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());
    }

最佳答案

除非您显式更改模拟的默认行为,否则它将返回 "nice values" .对于集合,默认返回值为空集合,因此您无需像注释掉的代码那样显式使用 when 调用来返回此类空集合。

关于java - 为什么在不定义 "when"方法的情况下使用 Mockito 进行 JUnit 测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51320563/

相关文章:

java - 如何从 jsp 文件中模型的特定列打​​印 java arrayList 的值

java - 从测试中获取 JUNIT 结果以将其结果发布到 testrail

java - 尝试加载InitialContext时出现ClassNotFoundException : org. jboss.naming.remote.client.InitialContextFactory

java - 单元测试 Java switch - 案例逻辑 - 多个单独的函数或多次调用

java - 渲染时定义的 Spring Webflow 操作未在单元测试中调用

java - ItemOnClick 监听器 Android

java - for 循环将对象的某些字段添加到数组列表中

java - 如何将自定义类对象注入(inject)Junit环境?

java - java 如何断言AssertionError?

java - 在 Mockito 中 stub 默认值