Vit*_*lii 1 mocking jdbctemplate mockito
我需要为此代码创建测试。
@Autowired
JdbcTemplate jdbcTemplate;
public List<Row> getData(int id) {
// Preconditions here
SimpleJdbcCall getCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName(SCHEMA)
.withProcedureName(SP)
.declareParameters(
// ...
)
.returningResultSet("result", (RowMapper<QuestionAnswerRow>) (rs, rowNum) -> .....);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("id", id);
// other parameters here
Map queryRes = getCall.execute(params);
List<row> res = (List<row>) queryRes.get("result");
return res;
}
Run Code Online (Sandbox Code Playgroud)
你能告诉我如何getCall.execute(params)用 Mockito模拟这里的响应吗?
您的问题是,您getCall在方法中创建了整个对象,这使得以某种方式将模拟注入该过程几乎是不可能的。
这里有几种可能性:
a)您可以模拟您的jdbcTemplate,然后尝试通过模拟getCall将对jdbcTemplate. 由于jdbcTemplate可能会完成所有实际的数据库工作,这可以工作,但老实说,这可能不值得付出努力(因为它绝对不是微不足道的)。
b) 例如,您可以将整个测试切换到集成测试,让它针对内存数据库运行。当然,有很多反对使用集成测试代替单元测试的争论,所以这可能也不是最好的方法。但是,这是可能的,并且使用 Spring 测试工具和注释可以非常简单。
c) 这给我们留下了一些工作,在这种情况下意味着重构:
由于您的问题是您在内部创建 SimpleJdbcCall,因此一种解决方案是将该部分提取到工厂中。这个简化的例子表明:
@Component
class SimpleJdbcCallFactory {
public SimpleJdbcCall create(JdbcTemplate template) {
return new SimpleJdbcCall(template);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以向类添加 @Autowired 依赖项,然后在单元测试中模拟该依赖项...
@RunWith(MockitoJUnitRunner.class)
public class YourTestClassHere {
@Mock
private SimpleJdbcCallFactory simpleJdbcCallFactory;
@InjectMocks
private YourClassHere classToTest;
@Test
public void test() {
SimpleJdbcCall mockedCall = Mockito.mock(SimpleJdbcCall.class);
Mockito.when( simpleJdbcCallFactory.create(Mockito.any())).thenReturn(mockedCall);
Mockito.when( mockedCall ).withSchemaName(Mockito.anyString()).thenReturn(mockedCall);
// etc. unfortunately needed for fluent apis (unless they added those in mockito)
Mockito.when( mockedCall.execute(Mockito.any()).thenReturn( ... );
classToTest.getData(123);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5100 次 |
| 最近记录: |