如何测试 SimpleJdbcCall [英] How to test SimpleJdbcCall

查看:34
本文介绍了如何测试 SimpleJdbcCall的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为此代码创建测试.

I need to create test for this code.

@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;
}

你能告诉我如何在这里模拟 getCall.execute(params) 使用 Mockito 响应吗?

Could you show me how can I mock here getCall.execute(params) response with Mockito?

推荐答案

您的问题是,您在方法中创建了整个 getCall 对象,这使得几乎不可能以某种方式注入模拟该过程.

Your problem here is, that you create the whole getCall object inside your method, which makes it pretty much impossible to somehow inject a mock into that process.

这里有几种可能性:

a) 您可以模拟您的 jdbcTemplate,然后尝试通过模拟 getCall 将对 jdbcTemplate 进行的所有调用来使其工作.由于 jdbcTemplate 可能会完成所有实际的数据库工作,因此这可以工作,但老实说,这可能不值得付出努力(因为它绝对不是微不足道的).

a) You can mock your jdbcTemplate and then try to get that to work by mocking all calls that getCall will make to the jdbcTemplate. Since the jdbcTemplate will probably do all the actual db work, this can work, but honestly, it's probably not worth the effort (since it's absolutely non-trivial).

b) 例如,您可以将整个测试切换到集成测试,让它针对内存中的数据库运行.当然,有很多反对使用集成测试代替单元测试的论据,所以这可能也不是最好的方法.不过,这是可能的,并且使用 Spring 测试工具和注释可以非常简单.

b) You can switch the whole test to an integration-test, letting it run against an in-memory db, for example. Of course, there are many arguments against using an integration test as a substitute for an unit test, so probably this isn't the best way to go, either. It's possible, though, and using the Spring test utils and annotations it can be pretty simple.

c) 这给我们留下了一些工作,在这种情况下意味着重构:

c) This leaves us with a bit of work, which in this case means refactoring:

由于您的问题是您在内部创建了 SimpleJdbcCall,因此一种解决方案是将该部分提取到例如工厂中.这个简化的例子表明:

Since your problem is that you create the SimpleJdbcCall internally, one solution would be to to extract that part, for example, into a factory. This simplified example shows that:

@Component
class SimpleJdbcCallFactory {
   public SimpleJdbcCall create(JdbcTemplate template) {
       return new SimpleJdbcCall(template);
   }
}

现在您可以向您的类添加一个 @Autowired 依赖项,然后在您的单元测试中模拟该依赖项...

Now you can add an @Autowired dependency to your class and then mock that depencency in your unit test...

@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);
   }

}

这篇关于如何测试 SimpleJdbcCall的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆