如何在java中模拟单个语句
我想使用Spring和JDBC实现一个数据库读取器如何在java中模拟单个语句,java,spring,unit-testing,mockito,Java,Spring,Unit Testing,Mockito,我想使用Spring和JDBC实现一个数据库读取器 @Component public class MyReader() { public void read() { /* Other code */ ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ String myDbValue = rs.getString("myColumn");
@Component
public class MyReader() {
public void read() {
/* Other code */
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
String myDbValue = rs.getString("myColumn");
}
/* Other code */
}
}
如果columnmyColumn
不存在,我想测试我的类的行为
一种解决方案是将常量myColumn
移动到一个私有方法,但是一些人告诉其他用户,这是一种嘲弄,请看Raedwalds的评论,我同意。
我也可以模拟数据库文件本身,但是
有什么想法可以处理这个问题吗?您的测试代码,以及您选择模拟的内容/方式,与您正在测试的方法的功能有着内在的、不可分割的联系。现在,这并不意味着它应该与该方法的实现相联系(您希望将其保持相当的解耦),但该方法的核心目的是要测试什么。这就是为什么精心设计、深思熟虑的测试能够驱动良好的API设计 因此,您需要问自己的问题是
read
方法在做什么
我怀疑执行查询返回的语句
和结果集
都是实现细节,您可以出于测试目的模拟这些细节
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.mockito.Matchers.*;
import java.sql.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class MyReaderTest {
@InjectMocks
private MyReader myReader;
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
Statement s = mock(Statement.class);
ResultSet rs = mock(ResultSet.class);
when(s.executeQuery(anyString())).thenReturn(rs);
when(rs.getString("myColumn")).thenThrow(SQLException.class);
}
@Test
public void testRead_AccessNonExistentColumn() {
// Use mock statement and mock resultset
}
}
我认为您应该在
rs.getString(“myColumn”)
中使用异常处理来执行测试。。如果引发任何异常,则将其抛出此行,并捕获调用方方法@用户3417078一个更大的问题是,为什么要检查myColumn
不存在?除此之外,您可以重构代码,以便传递ResultSet
,或者理想情况下将其接口作为方法的参数。通过这种方式,您可以在测试期间模拟接口并传递给您的方法。简单地说,模拟您得到的一切?@user6601906模拟的全部目的是测试函数行为,而不是在该函数中调用的函数的行为。因此,可以模拟此函数之外与第三方系统对话的任何调用。