我试图用Mockito模拟一些数据进行测试,但是我无法让它工作。我的问题是,我想模拟的值是我需要测试的方法中调用的返回值。
我有一个类MyAccessor.java
(它实现了一个服务MyService.java
),其中有一个方法getMyMethod(String value)
,在该方法中有一个对DB的调用:
final List<MyType> results = this.jdbcTemplate.query(sqlQuery, new RowMapper<MyType>() {
@Override
public MyType mapRow(final ResultSet rs, final int rowNum) throws SQLException {
final int fieldA = rs.getInt("column_name_1");
final int fieldB = rs.getInt("column_name_2");
final int fieldC = rs.getInt("column_name_3");
final int fieldD = rs.getInt("column_name_4");
return new MyType(fieldA , fieldB , fieldC , fieldD);
}
}, value);
有一种情况是由于数据库超时,rowMapper返回一个空列表。因此,在这种情况下,不可能执行return results.get(0)
,因为您将得到一个ArrayIndexOutOfBoundsException
。
于是我又查了一下:
if (!results.isEmpty()) {
return results.get(0);
} else {
return new MyType(0, 0, 0, 0);
}
现在,我想测试这个特定的场景,但是我不知道如何模拟resultSet返回,以便rowMapper返回一个空列表。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { ".....", "....."})
@TestPropertySource(".....")
public class MyClassTest {
@Mock
private JdbcTemplate jdbcTemplate;
@InjectMocks
@Autowired
private MyService myService;
@Before
public void initMocks() {
MockitoAnnotations.openMocks(this);
}
@Test
public void myTestMethod() {
Mockito.when(this.jdbcTemplate.query("SELECT NULL LIMIT 0", new RowMapper<Object>() {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
return new ArrayList<>();
}
})).thenReturn(new ArrayList<Object>());
MyType result = this.myService.getMyMethod("value");
assertEquals(0, result.getFieldA());
assertEquals(0, result.getFieldB());
assertEquals(0, result.getFieldC());
assertEquals(0, result.getFieldD());
}
}
但是测试失败了,因为返回的结果来自数据库,而不是空列表来测试超时情况。
我认为问题可能是因为我在服务接口而不是实现中注入了mock,但我想知道是否可以以某种方式完成,这样我就不必为该接口的每个实现测试mock。
或者,我可能使用了错误的Mockito框架,在这种情况下,我如何才能正确地测试?
注册。
2条答案
按热度按时间rxztt3cl1#
我觉得你更想要的是:
原因是,当你嘲笑的时候,你说只有当
query
的两个参数都和你定义的完全一样的时候才返回空列表。在你的例子中,你不关心RowMapper
的确切示例。jhdbpxl92#
我发现了问题。我在接口中注入了mock,而不是在接口的实现中。所以我不得不改变:
至:
在测试中:
至:
我不知道是否有更好的方法来实现这一点,而不必示例化服务可能具有的所有实现。
祝你好运