在我们公司,我们有一个服务层,它接收一些请求 XML,通过 JDBC 访问各种存储过程 (SP),处理数据并使用一些响应 XML 进行响应。最近人们开始在他们的 JUnit 测试中采用 MockRunner 来模拟来自 SP 的响应。使用 MockRunner 从 SP 设置模拟响应的代码看起来很糟糕(这是我打开的第一个随机测试类):
MockConnection connection = new MockConnection();
MockContextFactory.setAsInitial();
InitialContext context = new InitialContext();
context.rebind(READ_PAYMENT_DATA_SOURCE, getDS());
getDS().setupConnection(connection);
m_csStatementHandler = connection.getCallableStatementResultSetHandler();
m_csStatementHandler.clearResultSets();
m_csStatementHandler.clearCallableStatements();
m_csStatementHandler.setExactMatch(false);
m_csStatementHandler.prepareReturnsResultSet(READ_PAYMENT, true);
m_csStatementHandler.setExactMatch(false);
m_csStatementHandler.setExactMatchParameter(false);
Map parameterMap = new HashMap();
parameterMap.put(new Integer(1), null);
parameterMap.put(new Integer(2), null);
parameterMap.put(new Integer(3), null);
parameterMap.put(new Integer(4), null);
m_csStatementHandler.prepareOutParameter(READ_PAYMENT, parameterMap);
//Set up the cursor of applications for return.
MockResultSet resultApps = m_csStatementHandler.createResultSet();
resultApps.addRow(getPaymentSchedule("E", "Monthly", new Short("1"),null,null,null,null,null,null,null));
resultApps.addRow(getPaymentSchedule("A", "Weekly", new Short("1"),null,null,null,null,null,null,null));
resultApps.addRow(getPaymentSchedule("R", "Yearly", new Short("1"),null,null,null,null,null,null,null));
resultApps.addRow(getPaymentSchedule("S", "Weekly", new Short("1"),null,null,null,null,null,null,null));
resultApps.addRow(getPaymentSchedule("W", "Monthly", new Short("1"),null,null,null,null,null,null,null));
MockResultSet[] results = new MockResultSet[1];
results[0] = resultApps;
m_csStatementHandler.prepareResultSet(READ_PAYMENT, resultApps);
上面的代码很糟糕,原因有很多,但它确实清楚地显示了设置存储过程响应的复杂性和开销。
迄今为止,我一直在使用手动依赖注入来注入实际调用存储过程的类。我所要做的就是创建一个模拟 SP 调用程序类(负责 SP 的实际执行)并设置我想要的响应数据。我对这种技术非常满意,而且它比上面的更简单,因为它专注于数据而不是担心实现细节。但我的问题是,你什么时候想使用 MockRunner?单元测试似乎有点矫枉过正,所以我猜它更多地用于集成或系统测试?即便如此,我仍然觉得使用 DI 框架替换 SP 调用程序类然后为每个存储过程调用设置上面的所有代码更容易。请赐教!谢谢