【问题标题】:Unit testing: how much do I need to mock?单元测试:我需要模拟多少?
【发布时间】:2015-10-22 07:59:57
【问题描述】:

我目前正在开始进行单元测试,但我不知道要模拟什么,不应该模拟什么。我的理解是我要测试的类应该是完全隔离的,所以它只处理模拟。

例如,如果我有一个包含方法的类,它会调用getAnyobject()。然后它调用它的anyObject.getId() 方法并存储它。在我的单元测试中,我编写了一个方法build(),在这里我创建了一个AnyObjectanyObj 的实例。然后我用setId(01) 设置了一个ID。

在构建完所有内容后,我编写了一个测试方法。我在那里写:doReturn(anyObj).when(classUnderTest.theServiceIuse.getAnyObject())。我这样做是因为如果serviceIuse.getAnyObject() 不能正常工作,我的测试就会失败。除此之外,我还必须模拟 AnyObject 类中的 getID() 方法。因为我不想测试AnyObject 类。

这真的是我需要模拟这么多,还是我什至不需要调用setID() 方法?

【问题讨论】:

  • 可以添加你要测试的代码吗?我认为您正在尝试测试 getter 方法,但感觉不对劲。

标签: java spring unit-testing junit mockito


【解决方案1】:

请记住这一点。如果代码被编写为易于测试,那么模拟就没有必要了。例如,您可以只用空实现覆盖方法。

这就是为什么您几乎不需要模拟 POJO;您可以轻松地创建一个实例并使用它。当代码调用“做太多”(例如与数据库对话)或具有太多依赖项的方法时,您需要模拟。

一个典型的案例是测试服务Foo。在实际代码中,Foo 需要其他服务来完成它的工作。对于测试,您只想确保 Foo 正确使用其他服务(即检查 API 是否遵守);您实际上并不希望其他服务做任何事情。问题是你不能轻易地从测试中禁用服务(比如告诉 Java“当方法 formatHarddrive() 被调用时不要做任何事情)。

解决方法是为服务创建一个模拟,然后以某种方式将其注入Foo。模拟只是公开了尽可能少的 API。

模拟的另一个原因是测试错误处理。为此,您需要在代码中的某些点出现异常。模拟框架提供了舒适的方法来实现这一点。

【讨论】:

  • 问题是,目前我正在为已经存在的类编写测试,只是为了尝试一下。但问题是,我问自己,当我没有类时,我可以看到方法中发生了什么,我确实需要知道该类可以调用哪些其他方法。
  • 要编写一个测试,你需要知道你的代码在做什么。有一种称为黑盒测试的方法,但这主要与安全性相关(您用各种输入轰炸代码以查看它是否中断)。对于单元测试,你必须有源代码。
  • 但据我所知,测试驱动开发的原则是在编写实际代码之前编写测试。所以是的,我确实知道,我的代码最终应该做什么,但是我不知道这是如何完成的,以及使用哪个类的哪些方法......
  • TDD 适用于新代码,而不适用于现有代码。对于现有代码,您编写测试(尽可能好),然后重构和简化代码+测试(以确保新代码仍然像以前一样运行)。
【解决方案2】:

大多数时候。我将首先编写较低级别的类代码而不是模拟。当模块不在此包中开发或不依赖其他服务代码时,我将使用mock。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 2011-12-04
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 2017-02-11
    相关资源
    最近更新 更多