我想使用Spring和JDBC实现数据库阅读器。
@Component
public class MyReader() {
public void read() {
/* Other code */
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
String myDbValue = rs.getString("myColumn");
}
/* Other code */
}
}
如果列myColumn
不存在,我想测试我的课程的行为。
一个解决方案是将常量myColumn
移动到私有方法,但SO上的一些人告诉其他用户,嘲笑private methods smells,请参阅Raedwalds评论,我同意。
我也可以模拟数据库文件本身,但是mocking files isn't a good way too。
任何想法如何处理这个问题?
答案 0 :(得分:3)
您的测试代码,以及您选择模拟的内容和方式,与您正在测试的方法的功能有着内在和不可分割的联系。现在,这并不意味着它应该与该方法的实现相关联(您希望保持这种相当分离),但该方法的目的是做什么的核心目的是什么你应该测试。这就是精心设计,经过深思熟虑的测试推动良好API设计的原因。
您需要问自己的问题是 read
方法在做什么?。
我怀疑执行查询时返回的Statement
和ResultSet
都是您可以为测试目的而模拟的实现细节。
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
}
}