Easymock部分嘲笑(EasyMock ClassExtension),好还是坏?

时间:2009-11-19 13:39:58

标签: java unit-testing easymock

我使用EasyMock写了很多Mock对象。然而,我经常发现编写部分模拟时间很长,而且感觉不对“。”

我说它是一个设计错误,因为我尝试模拟我的类有多个问题,因此我应该创建单独的类以分离关注。

你怎么看?是部分嘲笑好事还是坏事?而且,如果好/坏,为什么?如果你注意到你不能模拟对象,你会建议你做什么,因为你只想模拟一些方法?

3 个答案:

答案 0 :(得分:4)

如果您发现自己定期创建部分模拟,则可能表明过多的状态和功能被投入到少量类中。这可能会使您的代码更难以维护和推理,因此更难以进行单元测试。如果您稍后发现系统中的某些其他组件需要其中一个大类中包含的功能的子集,它还可能导致代码重复或循环依赖。

尝试识别相关的功能组,并将其分解为可以独立进行单元测试的较小辅助类。这将使代码更易于理解,使您能够编写更细粒度的单元测试,并且您可能会发现有机会重用您在将来某个时间在不同上下文中拆分的功能。如果你正在使用像Spring或Guice这样的依赖注入框架,那么当你的应用程序运行时,很容易将这些对象连接在一起。

找出重构大班的最佳方法是通过经验学习的东西。但是,一般来说,我会尝试查看类正在做什么,并为处理中不同点的不同角色命名。然后我为这些角色创建新类。例如,如果我有一个读取服务器日志文件的类,并在那里找到某些条目时通过电子邮件发送给管理员,我可能会将其重构为一个知道如何解析日志文件的类,另一个查找触发条目的类,第三个知道如何通知管理员。诀窍是限制每个类中包含多少“知识”。这也让您有机会抽象出一般概念。例如,通过这种方式破坏您的类,您可以在将来支持不同的通知机制或各种触发条件,而不会影响您的日志解析类或其单元测试。

答案 1 :(得分:0)

我个人不是部分嘲笑的粉丝,因为这意味着你对ClassA的测试在某种程度上取决于ClassB的行为 - 而嘲弄的重点是能够测试ClassA独立于其中任何一个colloborators的实施细节。

我对你的意思感到困惑,“你只想嘲笑一些方法”。您使用的是什么版本的EasyMock?通常,您只需要为实际调用的方法提供期望值和返回值。或者你的意思是你正在编写这些类的存根版本?

如果您担心您的colloborator“有多个问题”,您可以尝试将其界面分解为几个不同的界面 - 实现类可以实现所有这些。这样,即使您的实现仍然只是一个类,您也可以在单元测试中提供不同的模拟(每个接口一个)。

答案 2 :(得分:0)

我的观点是:部分嘲笑很好,特别是当你:

•调用JNI方法的模拟方法,例如

public void methodToTest() {
    int result = invokeLibraryCode();
}

// This method will be mocked
int invokeLibraryCode() {
    // This method is native:
    com.3rdparty.Library.invokeMethod(); 
}

•使用当前日期操作的模拟方法,同时需要控制日期:

public void methodToTest() {
    Calendar cal = getCurrentDate();
}

// This method will be mocked
Calendar getCurrentDate() {
    return Calendar.getInstance();
}

•mock InputStreamProcess和其他抽象类:

public void methodToTest(InputStream is) throws IOException {
    int i = is.read(); // is.read() is mocked
}

当然,您可以使用接口覆盖前两个案例(将com.3rdparty.Library包装到您自己的界面中,实现CurrentDateProvider等,但我认为这样做过于复杂了。)