Java JMockit没有实例化期望块中捕获的接口
我不确定我是否错误地使用了JMockit,或者我的设置中有问题。我在Eclipse中使用Jmit 1.32和JUnit 4.12 我的问题似乎是接口没有被捕获。特别是在Java JMockit没有实例化期望块中捕获的接口,java,junit,mocking,jmockit,expectations,Java,Junit,Mocking,Jmockit,Expectations,我不确定我是否错误地使用了JMockit,或者我的设置中有问题。我在Eclipse中使用Jmit 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
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;}
}
在此设置中,测试执行失败,NPE位于Expectations(){}
块的第一行。但是从教程等中,我希望已经创建了一个模拟实例。()
为了克服这个问题,我创建了显式模拟类,如下所示:
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();
public类ResultSetMockup扩展了实体模型{}
公共类PreparedStatementMockup扩展了MockUp
{
@模拟结果集executeQuery(){返回新的结果集锁定().getMockInstance();}
}
公共类ConnectionLockup扩展了实体模型
{
@模拟PreparedStatement prepareStatement(字符串sql)引发SQLException{
返回新的PreparedStatementMockup().getMockInstance();
}
}
@捕获
ResultSet-mockResultSet=new ResultSet-Lockup().getMockInstance();
@捕获
PreparedStatementMockStatement=新的PreparedStatementMockup().getMockInstance();
@捕获
Connection mockConn=new connectionLockup().getMockInstance();
此时,Expectations(){}
块很高兴,但似乎从未实际设置results
。通过设置断点,我看到rs.next()
总是失败。所以我想实际上没有什么东西被抓获
我做错了什么?或者我的设置中有什么东西阻止了JMockit的实际运行?我的问题似乎是JUnit的使用。我甚至尝试了一字不差的教程示例。但通过转换为TestNG,我的所有问题都消失了
似乎JMockit的期望块无法通过JUnit正确地连接到代码中。要么是电话没被认出来,要么就是假装没发生。我现在很好奇,有人使用JUnit吗?测试中的实际问题是,它混合了来自JUnit3(任何来自JUnit.framework)和JUnit4+(
org.JUnit
)的API。这是绝对不应该做的
JMockit只支持JUnit4API,不支持过时的JUnit3API。因此,只需删除“从junit.framework.TestCase扩展而来”,就可以了
顺便说一句,您的JavaIDE应该已经警告了这个错误。IntelliJ至少会在扩展JUnit 3 TestCase的类中立即显示“用“@Test”注释的方法“testGetDtoById()”
此外,测试(以及测试中的代码)还有其他几个错误…谢谢,Rogério。我将此标记为答案,因为它回答了原始问题。我永远不会知道混合API。Eclipse什么也没说,我只是从junit导入了当前的sdk。至于“其他错误”,我了解到这两个mockResetSet.next()
调用不会按原样工作,应该是一个返回值为的单个调用(true,false)代码>。还有什么重要的事吗?在我的实际代码中,我已经切换到testng,并使大部分内容都正常工作。但我仍然难以将@capture与mocking具体方法结合起来。我猜这是一个否定吗?@Didjit在ClassUnderTest
中,我只看到一个对rs.next()
的调用,所以不需要为它记录两个返回值。其他事项:1)测试需要记录rs.getInt(1)
调用,否则将返回零;2) Dto
没有被模拟,因此对构造函数的期望没有意义;3) 对preparest陈述
和setInt
的期望并不是真正需要的;4) 吞下SQLException
不是一个好主意-而是将它们包装在newruntimeexception(e)
中。所有这些都是很好的反馈,@Rogério。谢谢那么,为了拦截构造函数,Dto
必须被显式模拟?也就是说,这不是自动发生的?我包含了prepareStatement
,这样它将返回一个(模拟的)对象,而不是null。我是不是遗漏了什么setInt()
是一种测试,但我想我必须添加times=1
才能使它有任何用处,对吗?我真的很喜欢你的框架的想法和功能,但我承认学习如何有效地使用它是一个挑战。(哦,还有例外——这只是为了保持代码干净。:-D)由于级联模拟(始终处于活动状态),模拟的PreparedStatement
将从mockConn
自动返回。与结果集
相同<在这种情况下,不应模拟code>Dto
(或者永远不会,因为它是一个“值对象”,通常不会模拟此类对象)。
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);
}
}
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();