JMockit未在Expectations块中

时间:2017-06-23 00:04:29

标签: java junit mocking jmockit expectations

我不确定我是否错误地使用了JMockit,或者我的设置中出现了什么问题。我在Eclipse中使用JMockit 1.32和JUnit 4.12。

我的问题似乎是接口没有被捕获。具体在java.sql包中。例如:

public class Dto {
    private int id;

    public Dto(){}

    public Dto(ResultSet rs) {
        try {
            id = rs.getInt(1);
        } catch (SQLException e) { }
    }

    public int getId() {return id;}
    void setId(int id) {this.id = id;}
}

public class ClassUnderTest {
    public static Dto loadObject(Connection conn, String tablename, int id) {
        Dto result = null;
        ResultSet rs = null;
        PreparedStatement ps = null;

        try {
            String sql = "select * from " + tablename + " where id = ?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, id);

            rs = ps.executeQuery();
            if (rs.next()) {
                result = new Dto(rs);
            }

        } catch (SQLException e) {  
        } finally {
            try {
                if (ps != null) ps.close();
            } catch (SQLException e) { }
        }

        return result;
    }
}

public class ResultSetTest  extends junit.framework.TestCase {

    private static final int OBJ_ID = 5;

    @Capturing
    ResultSet mockResultSet;

    @Capturing
    PreparedStatement mockStatement;

    @Capturing
    Connection mockConn;



    @Test
    public void testGetDtoById() throws SQLException {

        new Expectations() {{
            mockConn.prepareStatement(anyString);  result = mockStatement;
            mockStatement.setInt(anyInt, OBJ_ID);
            mockResultSet.next();                  result = true;
            new Dto(mockResultSet);                result = new Dto();
            mockResultSet.next();                  result = true;
        }};

        Dto dto = ClassUnderTest.loadObject(mockConn, "", OBJ_ID);

        assertEquals(dto.getId(), OBJ_ID);    
    }
}

在此设置中,测试执行失败,并在Expectations(){}块的第一行上显示NPE。但是从教程等开始,我预计会创建一个模拟实例。 (e.g. tutorial

试图超越这个,我创建了如此明确的模拟类:

public class ResultSetMockup extends MockUp<ResultSet> { }

public class PreparedStatementMockup extends MockUp<PreparedStatement>
{    
    @Mock ResultSet executeQuery() {return new ResultSetMockup().getMockInstance();}
}

public class ConnectionMockup extends MockUp<Connection> 
{
    @Mock PreparedStatement prepareStatement(String sql) throws SQLException { 
        return new PreparedStatementMockup().getMockInstance(); 
    }
}

@Capturing
ResultSet mockResultSet = new ResultSetMockup().getMockInstance();

@Capturing
PreparedStatement mockStatement = new PreparedStatementMockup().getMockInstance();

@Capturing
Connection mockConn = new ConnectionMockup().getMockInstance();

此时,Expectations() {}块很高兴,但似乎results实际上从未被设置过。通过设置断点,我发现rs.next()总是失败。所以我认为实际上没有任何东西被捕获。

我做错了什么?或者是我的设置中阻止JMockit实际运行的东西?

2 个答案:

答案 0 :(得分:0)

我的问题似乎是使用了JUnit。我没有运气就一字不差地尝试教程示例。但是通过转换到TestNG,我的所有问题都消失了。

似乎JMockit的Expectations阻止了JUnit无法正确挂钩代码。任何一个电话都没有被识别,或者假装没有发生。我现在很好奇,有没有人让它与JUnit合作?

答案 1 :(得分:0)

测试中的实际问题是它混合了来自JUnit 3(来自junit.framework)和JUnit 4+(org.junit)的API。永远不应该这样做。

JMockit仅支持JUnit 4 API,而不支持过时的JUnit 3 API。所以,只需删除&#34; extends from junit.framework.TestCase&#34;它会好的。

顺便说一下,你的Java IDE应该警告这个错误。 IntelliJ,至少,迅速显示&#34;方法&#39; testGetDtoById()&#39;用&#39; @ Test&#39;注释内部类扩展JUnit 3 TestCase&#34;。

此外,测试(以及测试中的代码)还有其他一些错误......