Java 如果我已经有存根,模拟库是多余的吗?
假设我在各自的源文件夹/包中有以下类Java 如果我已经有存根,模拟库是多余的吗?,java,unit-testing,mocking,data-access-layer,Java,Unit Testing,Mocking,Data Access Layer,假设我在各自的源文件夹/包中有以下类 [src/myApp] |_Employee «concrete» |_Manager «abstract» |_ManagerImpl «concrete» (Class Under Test) |_Recruiter «abstract» |_RecruiterImpl «concrete» (Collaborator) 以下是我的问题:鉴于我有一个招聘人员标准的具体实现,它已经存在于代码库中,用于测试目的(在测试范围内) 在上述单元测试中
[src/myApp]
|_Employee «concrete»
|_Manager «abstract»
|_ManagerImpl «concrete» (Class Under Test)
|_Recruiter «abstract»
|_RecruiterImpl «concrete» (Collaborator)
以下是我的问题:鉴于我有一个招聘人员标准
的具体实现,它已经存在于代码库中,用于测试目的(在测试
范围内)
RecruiterStandIn
完成了被测类在上述单元测试中所需的一切工作。也就是说,为了简单的回答/解释,没有必要将上面的场景过度复杂化,人为地假设存根的维护等等
提前感谢。我对您具体问题的回答:
RecruiterStandIn
。相反,我会设置新兵返回罐装答案,这样您就不必维护两个类来返回一些预定义的数据:
@Spy
private Recruiter recR;
public void testGrowTeam( ) {
// Setup canned data return
doReturn(generateTestEmployee()).when(recR).srcEmployee(any(Object.class));
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
仅供参考上述语法将用于使用Mockito。从我在你的案例中所能告诉你的,Mockito给了你在不需要你创建新的测试实体的情况下剔除某些部分和更多部分的能力
原始答案
当然是的,你应该做模拟对象测试。模拟对象测试允许您测试类之间的交互,并确保事物正确地与它们周围的世界交互。我认为,当您第一次编写类及其相应的测试时,这些测试的价值较小。一年后,当一个新的开发人员进来时,由于她不理解需要某些内部行为,而无意中破坏了您的代码,模拟对象测试就会大放异彩
一个有点做作的例子是,假设我们有一辆汽车需要加满一些汽油:
public class Car {
public void fuelUp()
}
现在,通过标准的单元测试,我们将在调用fuelUp()
后检查汽车是否充满汽油,以及是否从驾驶员那里扣除了适当的金额。但由于我们从未测试过fuelUp()
是如何与周围世界进行交互的,因此它很容易做到以下几点:
public void fueldUp() {
siphonGasFromNearestCar();
buyCoffeeAndChips()
}
但通过模拟对象测试,您可以确保车辆以正确和预期的方式加注。谢谢tkeE2036。我已经被嘲弄了。不过还是要感谢你的布道。我仍然很感激对我的问题的答案——我认为你忽略了这个问题。如果你发现我的文章有帮助,请考虑接受它来帮助未来的人:)冒着不领情的风险,如果我的问题是,“我应该做模拟对象测试吗?”那么你就对钱了。如果我的注意力集中在“路上”的某段时间,那么你就要打1000球了。然而,事实上,我现在只关注上面的例子。我特别想问的是,鉴于上面的例子,使用mock是否是多余的。只是。正如我在我的帖子中所说,正如我现在所写的,这是多余的。我接着说,我会去掉你的存根,使用一个框架来创建你的存根,即使你永远不想做模拟测试。精彩的后续!我将您对Q2的回答理解为“值是,您不必维护两个类来返回一些预定义的数据”。对吗?但你指的是哪两类<代码>招聘人员必须留下<代码>员工必须留下。我可以看到失去了一门课(
RecruiterStandIn
)。但是,你认为第二个输的是哪一个呢?
public class ManagerImplTest {
...
// Class Under Test
private ManagerImpl mgr;
// Collaborator
private Recruiter recR = new RecruiterStandIn( );
...
public void testGrowTeam( ) {
//...
mgr.setRecruiter( recR );
mgr.growTeam( criteria );
// assertions follow...
}
...
}
...
@Mock
private Recruiter recR;
...
...
public void testGrowTeam( ) {
...
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
...
@Spy
private Recruiter recR;
public void testGrowTeam( ) {
// Setup canned data return
doReturn(generateTestEmployee()).when(recR).srcEmployee(any(Object.class));
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
public class Car {
public void fuelUp()
}
public void fueldUp() {
siphonGasFromNearestCar();
buyCoffeeAndChips()
}