我有这个类,想要创建一个模拟来返回并验证返回值“50”:
QAService.java:
@Path("/QAService")
public class QAService {
@GET()
//@Path("/")
@Produces("text/plain")
public String getServiceInfo() {
return "50";
}
我对定义模拟的理解是我可以创建一个实现类的假对象和模拟函数,但是我可以测试接口。
仍然我正在创建此测试来测试没有接口的模拟。我如何验证?:
QAServiceTest.java:
public class QAServiceTest {
@Test
public void getserviceTest () {
QAService qasmock = mock(QAService.class);
when(qasmock.getServiceInfo()).thenReturn("50");
String expected = "50";
assertEquals(expected, qasmock.getServiceInfo());
}
}
答案 0 :(得分:17)
让我们直接得到几个定义,首先:
单元测试是您编写的一小段代码,用于确保您开发的系统运行正常。单元测试通常在JUnit
这样的框架中创建,但不需要。例如,单元测试将assertEquals(5, calculator.add(2, 3))
。
mock 是对真实系统的模仿,通常用于单元测试。模拟通常在Mockito
或EasyMock
等框架中创建,但不需要。模拟是“测试双重”的一种形式 - 用于代替实际系统的代码的通用术语,用于测试目的 - 而Martin Fowler在名为"Mocks Aren't Stubs"的文章中更准确地定义它们。
在编写单元测试时,您尝试测试单个单元,通常称为受测试系统或 SUT 。每个测试可能都有一个不同的系统正在测试中,关键是您在测试中测试的代码是您的真实的,实际的代码,而不是任何类型的模拟或虚假实现。
在复杂的应用程序中,您的类可能需要与可能编写或未编写或编译的其他类协作,这些类通常称为依赖项。任何给定的类或系统可能都有自己的依赖项,并且可能是其他系统的依赖项。模拟框架适用于模拟这些依赖项,而不是模拟被测系统。
对于您的示例,QAService是您正在编写的主类(被测系统),QAServiceTest是该系统的单元测试。 不一定需要嘲笑。
假设QAService依赖于另一个尚未编写的类,称为“StorageService”。在编写QAService测试之前,您不一定要等待StorageService工作,因此不使用真正的StorageService,而是使用 mock 。同样,在名为QAServiceTest的单元测试中,您使用真正的 QAService并模拟其依赖 StorageService。
即使您没有编写StorageService,您也可能对QAService如何使用该类有所期待。也许你知道当你致电storageService.store(qaRecord)
时,它应该返回一个数字ID,如101
。即使代码不起作用,您也可以创建一个Mockito mockStorageService
,并按照以下方式进行准备:
when(mockStorageService.store(expectedQARecord)).thenReturn(101);
现在让我们假设在测试结束时,您要确保您正在测试的QAService方法绝对会调用storageService.delete(101)
。 Mockito mockStorageService
会像这样检查:
verify(mockStorageService).delete(101);
通常不需要验证使用when
生成的语句,因为除非被测系统正确调用mock以获取返回值(此处为101),否则测试不太可能成功。
现在假设您已经编写了另一个名为QAApplication的代码块,您正在一个名为QAApplicationTest的单元测试中进行测试,该测试依赖于QAService。您可能没有完成或测试QAService,并且使用真正的QAService需要StorageService,因此您在单元测试中使用 mock QAService和真正的 QAApplication 称为QAApplicationTest。
所以,总而言之,模拟在单元测试中运行来模拟系统中的依赖 。在您的情况下,QAServiceTest不需要模拟QAService,但可能用于模拟QAService的依赖项。如果你确实需要一个模拟的QAService,那么在测试另一个QAService本身就是依赖的类时你需要它。
答案 1 :(得分:11)
Junit只会运行使用@Test
注释的方法,因此请添加
@Test
public void getserviceTest () {
QAService qasmock = mock(QAService.class);
when(qasmock.getServiceInfo()).thenReturn("50");
String expected = "50";
assertEquals(expected, qasmock.getServiceInfo());
}
另外,你应该verify()
你的模拟期望实际发生了。
verify(qasmock, times(1)).getServiceInfo();
请注意,您似乎想要测试QAService
,但实际上您并没有这样做。你只是在测试一个模拟器。那不是一回事。
自己创建QAService
对象并使用它。