【问题标题】:Mockito for SimpleJdbcCall with Spring JdbcTemplate带有 Spring JdbcTemplate 的 SimpleJdbcCall 的 Mockito
【发布时间】:2020-10-05 16:20:17
【问题描述】:

我尝试了多种方法在我的 Junit 测试用例中执行存储过程来测试输出值,但不幸的是没有任何效果。 我的测试用例:

public class DataTest {

    @Mock
    private static DataSource ds;

    @InjectMocks
    private DataDaoImpl dataDao = new DataDaoImpl();

    @Mock
    private static JdbcTemplate jdbcTemplate;

    @Mock
    private static SimpleJdbcCall viewProc;


    @Before
    public void setUp() throws IOException, InterruptedException {
        MockitoAnnotations.initMocks(this);
        MockMvcBuilders.standaloneSetup(dataDao).build();
    }

    @BeforeClass
    public static void init() throws Exception {
        viewProc = new SimpleJdbcCall(ds).withSchemaName("schema")
                .withProcedureName("viewProc").withoutProcedureColumnMetaDataAccess()
                .declareParameters(new SqlParameter("param1", Types.VARCHAR))
                .declareParameters(new SqlParameter("param2", Types.VARCHAR))
                .returningResultSet("dataModules", Mockito.anyObject());

        jdbcTemplate = new JdbcTemplate(ds);

    }

    @Test
    public void findDataModules() throws Exception {

        String param1 = "abc";
        List<DataObj> md = new ArrayList<DataObj>();


        int size = 3;
        SqlParameterSource in = new MapSqlParameterSource().addValue("param1", "abc").addValue("param2",
                "123");
        Map map = viewProc.execute(in);
        md = (List<DataObj>) map.get("data");
        assertTrue("Expected Data  ", md.size() >= size);


    }

}

我的主要课程:

@Repository
public class DataDaoImpl implements DataDao {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Resource(name = "db")
    private DataSource db;

    private SimpleJdbcCall viewProc;

    private JdbcTemplate jdbcTemplate;

    /**
     * Initialization of Stored Procs and JDBC Template
     * 
     * @throws Exception
     */
    @PostConstruct
    public void init() throws Exception {
        viewProc = new SimpleJdbcCall(db).withSchemaName("schema")
                .withProcedureName("viewProc").withoutProcedureColumnMetaDataAccess()
                .declareParameters(new SqlParameter("param1", Types.VARCHAR))
                .declareParameters(new SqlParameter("param2", Types.VARCHAR))
                .returningResultSet("data", new ViewDataRowMapper());

        jdbcTemplate = new JdbcTemplate(db);

    }

        @Override
    public List<Data> findUniqueDataModules(String p1, String p2) throws Exception {
        List<DataObj> dataModules = new ArrayList<DataObj>();
        try {
            SqlParameterSource in = new MapSqlParameterSource().addValue("param1", p1).addValue("param2",
                    p2);
            Map map = viewUniqueDataModulesByLicense.execute(in);
            dataModules = (List<DataObj>) map.get("data");
        } catch (Exception e) {
            //Hnadel Exception
        }
        return dataModules;
    }

    }

上面的代码给出了异常说数据源是必需的。 我尝试了 Mockito、powerMockito 但它返回空地图。模拟没有例外。 我可以接受任何可以通过我的测试用例的解决方案。 修改命名。

【问题讨论】:

  • 能否请您出示您要测试的代码?
  • @Mensur 更新了主类。

标签: junit mockito jdbctemplate powermockito simplejdbccall


【解决方案1】:

尽管我讨厌在测试中使用反射,但我相信它可以帮助您解决问题。在这里,在初始化之后,我将字段viewProc 设置为可以在测试中使用的模拟对象。 @PostConstruct是Spring相关的注解,所以初始化的时候不会被调用。

class DataDaoImplTest {

    private DataDaoImpl dataDao;

    @Mock
    private DataSource dataSource;

    @Mock
    private SimpleJdbcCall jdbcCall;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
        this.dataDao = new DataDaoImpl(dataSource);
        ReflectionTestUtils.setField(this.dataDao, "viewProc", jdbcCall);
    }

    @Test
    void findUniqueDataModules() throws Exception {
        // given:
        Map<String, Object> map = new HashMap<>();
        map.put("data", Arrays.asList(new DataDaoImpl.DataObj(), new DataDaoImpl.DataObj()));
        // mocks:
        when(jdbcCall.execute(any(SqlParameterSource.class))).thenReturn(map);
        // when:
        List<DataDaoImpl.DataObj> uniqueDataModules = this.dataDao.findUniqueDataModules("a", "b");
        // then:
        assertEquals(2, uniqueDataModules.size());
    }
}

另一种解决方案是针对测试数据库(如 H2)测试该方法。但这不会是单元测试。

【讨论】:

  • 感谢 Mensure,1) 我没有在构造函数中初始化 dataSource。 2) 我们没有方法DataObj(), new DataDaoImpl.DataObj()。
  • 我知道,但我只是尝试创建一个不一样的类似环境。关键是,您可以使用反射来注入模拟对象。
  • 知道了,我正在尝试使用它,但它会根据我创建的内容检查大小。
  • 另外请告诉我如何处理全局地图,我必须测试一个方法在类中全局定义地图。
  • 断言只是为了它而存在。我想不出比这更好的断言了。至于全球地图,你可以添加到原来的问题或创建一个新的问题,我们会看到。
猜你喜欢
  • 2021-05-20
  • 1970-01-01
  • 2015-10-06
  • 2011-01-25
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多