2010-08-03 52 views
0

在我们的公司,我们有一个服务层,它接受一些请求XML,通过JDBC访问各种存储过程(SP),处理数据并响应一些响应XML。最近人们开始在他们的JUnit测试中采用MockRunner来模拟SP的响应。该代码设置从SP的使用Mockrunner用嘲笑的回应看起来可怕(这是第一次随机测试类我打开):为什么我会使用MockRunner而不是正常/手动依赖注入?

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调用方类,然后为每个存储过程调用设置上述所有代码。请指教!谢谢

回答

2

最终你正在研究一般嘲笑背后的哲学。我会给你我的两分钱,但我也会提及你任何主要的嘲笑图书馆,这可能会为他们自己的存在提供很好的理由。以Mockito为例。

测试/模拟社区通常会区分手动滚动(通常称为“存根”(静态,手写类)和“模拟”(动态的,运行时生成的类) )。

嘲笑的好处是相当大的相比,只是存根。许多测试人员为了测试的目的而着迷于编写接口和/或子类具体类的实现。要做到这一点,通常需要实现所述类/接口的所有方法,即使你只是想测试一个特定的方法。

模拟让你可以通过定义你想要赋予行为的方法来解决这个问题,而且功能强大。另外,模拟允许你改变从一个测试到下一个测试的行为。要做到这一点与存根,你必须写一个全新的存根类。

从嘲笑库到库的语法都有所不同。有些人可能会发现比其他人更可读。我目前最喜欢的是Mockito,因此是早期的参考,但它们随着时间推移而发展。这可能是值得确定的,为什么你的组织使用嘲笑套件,它是否是另一个可能仍然满足你的需求以及更具可读性。

希望您的测试编写者将常见行为引入测试设置方法(如JUnit的@Before),因此您无需继续在各处看到模拟创建和常见初始化。

+0

感谢您的支持。我很熟悉我喜欢的Mockito。 – 2010-08-04 10:57:22