简体   繁体   English

Mockito模拟返回值并验证它

[英]Mockito Mocking a return value and verify it

I have this class and wants to create a mock to return and verify the return value "50": 我有这个类,并希望创建一个模拟返回并验证返回值“50”:
QAService.java:

@Path("/QAService")
public class QAService {
@GET()
//@Path("/")
@Produces("text/plain")
public String getServiceInfo() {
    return "50";
}

My understanding of mock by defintion is that I can create a fake object of an implementation class and mock functions yet to be developed so I can test the interface. 我对定义模拟的理解是我可以创建一个实现类的假对象和模拟函数,但是我可以测试接口。

Still I am creating this test to test mocking without having an interface. 我仍然在创建这个测试来测试没有接口的模拟。 How do I verify it?: 我该如何验证呢?:
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());
    }
}

Let's get a couple definitions straight, first: 让我们直接得到几个定义,首先:

  • A unit test is a brief bit of code you write to ensure that the system you've developed is behaving correctly. 单元测试是您编写的一小段代码,以确保您开发的系统运行正常。 Unit tests are often created in a framework like JUnit , but do not need to be. 单元测试通常在像JUnit这样的框架中创建,但不需要。 For example, a unit test would assertEquals(5, calculator.add(2, 3)) . 例如,单元测试将assertEquals(5, calculator.add(2, 3))

  • A mock is an imitation of a real system, which is often used in unit tests. 模拟是对真实系统的模仿,通常用于单元测试。 Mocks are often created in frameworks like Mockito or EasyMock , but do not need to be. 模拟通常在像MockitoEasyMock这样的框架中创建,但不需要。 Mocks are a form of "test double"—the general term for code you substitute in place of your actual systems, for testing purposes—and Martin Fowler defines them more exactly in an article called "Mocks Aren't Stubs" . 模拟是一种“测试双重”形式 - 用于代替实际系统的代码的通用术语,用于测试目的 - 而Martin Fowler在一篇名为“Mocks Are not Stubs”的文章中更准确地定义了它们。

  • When writing a unit test, you're trying to test a single unit, which is often called the system under test or SUT for short. 在编写单元测试时,您正在尝试测试单个单元,通常称为被测 系统或简称SUT Each test will probably have a different system under test, and the point is that the code that you are testing in the test is your real, actual code , not any sort of mock or fake implementation. 每个测试可能会有一个不同的系统正在测试中,重点是您在测试中测试的代码是您真实的实际代码 ,而不是任何类型的模拟或虚假实现。

  • In a complex application, your classes will probably need to collaborate with other classes that may or may not be written or tested, which are categorically known as dependencies . 在复杂的应用程序中,您的类可能需要与可能编写或测试的其他类协作,这些类通常称为依赖项 Any given class or system may have its own dependencies, and may be a dependency for other systems. 任何给定的类或系统可能都有自己的依赖项,并且可能是其他系统的依赖项。 Mocking frameworks are good for mocking those dependencies, not for mocking the system under test. 模拟框架有助于模拟这些依赖项,而不是模拟被测系统。


For your example, QAService is the main class you're writing (system under test), and QAServiceTest is the unit test for that system. 对于您的示例,QAService是您正在编写的主类(被测系统),QAServiceTest是该系统的单元测试。 No mocks are necessarily required. 不需要嘲笑。

Let's say that QAService depends on another class not yet written, called "StorageService". 假设QAService依赖于另一个尚未编写的类,称为“StorageService”。 You don't necessarily want to wait for StorageService to work before writing QAService's tests, so instead of using a real StorageService you use a mock . 在编写QAService测试之前,您不一定要等待StorageService工作,因此不使用真正的StorageService而是使用模拟 Again, in the unit test called QAServiceTest, you use a real QAService and mock its dependency StorageService. 同样,在名为QAServiceTest的单元测试中 ,您使用真正的 QAService并模拟其依赖 StorageService。

Even though you don't have StorageService written, you probably have some expectation about how QAService will use that class. 即使您没有编写StorageService,您也可能对QAService如何使用该类有所期待。 Maybe you know that when you call storageService.store(qaRecord) , it should return a numeric ID like 101 . 也许你知道当你调用storageService.store(qaRecord) ,它应该返回一个像101这样的数字ID。 Even without the code working, you can create a Mockito mockStorageService , and prepare it like this: 即使没有代码工作,您也可以创建一个Mockito mockStorageService ,并按照以下方式进行准备:

when(mockStorageService.store(expectedQARecord)).thenReturn(101);

Now let's say that at the end of the test, you want to ensure that the method of QAService that you're testing will absolutely call storageService.delete(101) . 现在让我们说在测试结束时,您要确保您正在测试的QAService方法绝对会调用storageService.delete(101) A Mockito mockStorageService would check that like this: Mockito mockStorageService会像这样检查:

verify(mockStorageService).delete(101);

It is often unnecessary to verify statements you have made with when , because the test is unlikely to succeed unless the system under test calls the mock correctly to get that return value (101 here). 通常不必验证使用when语句,因为测试不太可能成功,除非被测系统正确调用mock以获得返回值(此处为101)。

Now let's say that you've written another block of code called QAApplication, which you're testing in a unit test called QAApplicationTest, that depends on QAService. 现在让我们说你已经编写了另一个名为QAApplication的代码块,你正在一个名为QAApplicationTest的单元测试中测试,它依赖于QAService。 You may not have QAService finished or tested, and using a real QAService would require a StorageService, so instead you use mock QAService with a real QAApplication in your unit test called QAApplicationTest. 您可能没有完成或测试QAService,并且使用真正的QAService需要StorageService,因此您在单元测试中使用模拟 QAService和真正的 QAApplication,称为QAApplicationTest。


So, to sum up, a mock works within unit tests to mock the dependencies of the system under test . 因此,总而言之,模拟单元测试中工作以模拟被测系统依赖性 In your situation, QAServiceTest will not need a mock QAService, but may be used to mock the dependencies of QAService. 在您的情况下,QAServiceTest不需要模拟QAService,但可能用于模拟QAService的依赖项。 If you do need a mock QAService, you'll need it when testing another class where QAService itself is a dependency. 如果你确实需要一个模拟QAService,那么在测试另一个QAService本身是依赖的类时你需要它。

Junit will only run methods annotated with @Test , so add it Junit只会运行用@Test注释的方法,所以添加它

@Test
public void getserviceTest () {
    QAService qasmock = mock(QAService.class);
    when(qasmock.getServiceInfo()).thenReturn("50");
    String expected = "50";
    assertEquals(expected, qasmock.getServiceInfo());
}

Also, you should verify() that your mock expectations actually happened. 此外,您应该verify()您的模拟期望实际发生了。

verify(qasmock, times(1)).getServiceInfo();

Note that it seems like you want to test QAService , but you really aren't doing that here. 请注意,您似乎想要测试QAService ,但实际上您并没有这样做。 You are simply testing a mock. 你只是在测试一个模拟器。 That's not the same thing. 那不是一回事。

Create the QAService object yourself and use it. 自己创建QAService对象并使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM