Mock在要测试的实现接口的方法中返回ResultSet的值



我试图用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框架,在这种情况下,我如何才能正确测试?

富豪。

我想你想要更像的东西

@Test
public void myTestMethod() {
Mockito.when(this.jdbcTemplate.query(eq("SELECT NULL LIMIT 0"), Mockito.any(RowMapper.class))
.thenReturn(new ArrayList<Object>());
}

原因是在嘲笑时,您说只有当query的两个参数都与您定义的完全相同时,才返回空列表。在您的情况下,您不关心RowMapper的确切实例。

我发现了问题。我在接口中注入mock,而不是在接口的实现中。所以我不得不改变:

@Mock
private JdbcTemplate jdbcTemplate;
@InjectMocks
@Autowired
private MyService myService;

至:

@Mock
private JdbcTemplate jdbcTemplate;
@InjectMocks
@Autowired
private MyAccessor myAccessor;
@Autowired
private MyService myService;

在测试中:

MyType result = this.myService.getMyMethod("value");

至:

MyType result = this.myAccessor.getMyMethod("value");

我不知道是否有更好的方法可以做到这一点,而不必实例化服务可能拥有的所有实现。

谨致问候。

最新更新