使用 EasyMock 对扩展存储过程的 java 类进行单元测试

Posted

技术标签:

【中文标题】使用 EasyMock 对扩展存储过程的 java 类进行单元测试【英文标题】:Unit testing a java class extending Stored Procedure with EasyMock 【发布时间】:2013-04-04 20:27:09 【问题描述】:

当我尝试对扩展 StoredProcedure 的以下类进行单元测试时,我在以下行收到 NullPointerException:return (Map) execute(csc, new CallableStatementCallback() in JDBCTemplate 类。我模拟了在execute 方法、DataSource 和sql 中传递的bean。

public class MyStoredProc extends StoredProcedure 
    /**
     * Constructor - sets SQLParameters for the stored procedure.
     * 
     * @param ds - DataSource
     */
    public MyStoredProc(DataSource dataSource, String sql) 
        super(dataSource, sql);
        declareParameter(new SqlOutParameter("return",Types.NUMERIC));
        declareParameter(new SqlParameter("BATCH_ID",Types.NUMERIC));
        declareParameter(new SqlParameter("PROCESS_TYPE",Types.VARCHAR));

        complie(); 
    

    public BigDecimal execute(MyBean bean)
        BigDecimal returnValue = BigDecimal.valueOf(-1);

        Map in = new HashMap();

        in.put("BATCH_ID", bean.getBatchID());
        in.put("PROCESS_TYPE", bean.getProcessType());

        Object obj = execute(in);
        if (obj != null) 
            Object output = ((HashMap) obj).get("return"); 

            if( output instanceof BigDecimal) 
                returnValue = (BigDecimal)output;
            
        
        return bigDec; 
    

测试用例:P.S - 当我调试这个测试用例时,根本没有使用 StoredProcedure 模拟。而是使用了实际的实现。

public class MyStoredProcTest 
private MyStoredProc mysp;
private DataSource dataSource;
private String sql;
@Before
public void setUp() 
    dataSource = EasyMock.createMock(DataSource.class);
    sql = "Testing";
    mysp = new MyStoredProc(dataSource, sql);


@Test
public void testExecute() 

    StoredProcedure storedProcedure = EasyMock
            .createMock(StoredProcedure.class);
    HashMap map = new HashMap();
    map.put("return", BigDecimal.ONE);
    expect(storedProcedure.execute(EasyMock.anyObject(Map.class))).andReturn(map);

    Connection con = EasyMock.createMock(Connection.class);
    expect(dataSource.getConnection()).andReturn(con);   
    MyBean bean = EasyMock.createMock(MyBean.class);


    expect(bean.getBatchID()).andReturn(BigDecimal.valueOf(.0001))
            .anyTimes();
    expect(bean.getProcessType()).andReturn("Process Type").anyTimes();

    replay(bean, dataSource, storedProcedure, con);
    BigDecimal returnValue = null;
    try 
        returnValue = mysp.execute(bean);
     catch (Exception e) 
        System.out.println("exception" + e.getStackTrace());//  the Null pointer from JDBCTemplate is caught here.
    
    Assert.assertEquals(BigDecimal.valueOf(-1), returnValue);

【问题讨论】:

【参考方案1】:

您的某些模拟没有被使用,因为您没有重播它们。您应该将replay(bean) 修改为replay(bean, datasource, storedProcedure)

另一方面,map 不需要被嘲笑。当您希望调用 storedProcedure.execute(...) 时,您可以返回预填充的 map

【讨论】:

谢谢 jradakov...我仍然遇到同样的错误。我添加了重播,创建了一个地图实例而不是根据您的建议模拟它并添加了一个模拟连接(因为它给了我一个意想不到的调用 getConnection) 我忘记在重播中添加“con”...这样做了,现在出现了另一个错误...将尝试解决它并在需要任何帮助时发布

以上是关于使用 EasyMock 对扩展存储过程的 java 类进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

PowerMock

在套件测试期间,EasyMock 说 0 个匹配器预期 1 个记录

如何 EasyMock 对返回通配符泛型的方法的调用?

EasyMock:java.lang.IllegalStateException:预期 1 个匹配器,记录 2 个

java EasyMock对于有参无返回至的方法怎么模拟?

easymock笔记2