Java 单元测试:我需要模拟多少?

Java 单元测试:我需要模拟多少?,java,spring,unit-testing,junit,mockito,Java,Spring,Unit Testing,Junit,Mockito,我现在开始进行单元测试,我不知道该模仿什么,不该模仿什么。我所理解的是,我想要测试的类应该是完全隔离的,所以它只处理mock 例如,如果我有一个类,其中包含一个方法,它将调用getAnyobject()。然后调用它的anyObject.getId()方法并存储它。在单元测试中,我编写了一个方法build(),其中我创建了AnyObject,anyObj的一个实例。然后我用setId(01)设置一个ID 构建完所有内容后,我编写了一个测试方法。我在这里写到:doReturn(anyObj).whe

我现在开始进行单元测试,我不知道该模仿什么,不该模仿什么。我所理解的是,我想要测试的类应该是完全隔离的,所以它只处理mock

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

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


这真的是真的吗,我需要这么多的模拟,或者我甚至没有必要调用
setID()
方法吗?

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

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

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

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

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


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

您可以添加要测试的代码吗?我认为您正在尝试测试getter方法,但感觉有些不对劲。问题是,目前我正在编写测试对于已经存在的类,我只是想尝试一下。但问题是,我问自己,当我没有类时,我看到方法中发生了什么,我确实需要知道该类可以调用哪些其他方法。要编写测试,你需要知道你的代码在做什么。有一种方法叫做黑盒测试,但它主要与vant for security(您使用各种输入对代码进行轰炸,以查看其是否中断).对于单元测试,你必须拥有源代码。但是,据我所知,测试驱动开发的原则是,你在编写实际代码之前先编写测试。所以,是的,我知道,我的代码最终应该做什么,但我不知道如何完成,也不知道使用哪个类的哪些方法……TDD与新代码一起工作,而不是与e对于现有代码,您可以编写测试(尽可能好),然后重构并简化代码+测试(以确保新代码仍能像以前一样工作)。