Java Mockito 模拟返回值并验证它

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22099264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:36:16  来源:igfitidea点击:

Mockito Mocking a return value and verify it

javaunit-testingmockingmockito

提问by JustinBieber

I have this class and wants to create a mock to return and verify the return value "50":
QAService.java:

我有这个类,想创建一个模拟来返回并验证返回值“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.

我对 mock by defintion 的理解是,我可以创建一个实现类的假对象和尚未开发的模拟函数,以便我可以测试接口。

Still I am creating this test to test mocking without having an interface. How do I verify it?:
QAServiceTest.java:

我仍然创建这个测试来测试没有接口的模拟。我如何验证它?:
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());
    }
}

采纳答案by Sotirios Delimanolis

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. You are simply testing a mock. That's not the same thing.

请注意,您似乎想要 test QAService,但您实际上并没有在这里这样做。您只是在测试模拟。那不是一回事。

Create the QAServiceobject yourself and use it.

QAService自己创建对象并使用它。

回答by Jeff Bowman

Let's get a couple definitions straight, first:

让我们先明确几个定义:

  • A unit testis 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. For example, a unit test would assertEquals(5, calculator.add(2, 3)).

  • A mockis an imitation of a real system, which is often used in unit tests. Mocks are often created in frameworks like Mockitoor EasyMock, but do not need to be. 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".

  • When writing a unit test, you're trying to test a single unit, which is often called the system under testor SUTfor short. 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.

  • 一个单元测试是代码简短一点你写,以确保自己开发的系统行为正确。单元测试通常在类似 的框架中创建JUnit,但并非必须如此。例如,单元测试将assertEquals(5, calculator.add(2, 3)).

  • 模拟是真实的系统,其通常在单元测试中使用的模仿。模拟通常在Mockito或 等框架中创建EasyMock,但并非必须如此。Mock 是一种“测试替身”的形式——用于代替实际系统的代码的通用术语,用于测试目的——Martin Fowler 在一篇名为“Mocks Aren't Stubs”的文章中对它们进行了更准确的定义。

  • 编写单元测试时,您试图测试单个单元,通常称为被测系统或简称SUT。每个测试可能会有不同的被测系统,关键是您在测试中测试的代码是您真实的、实际的代码,而不是任何模拟或虚假的实现。

  • 在复杂的应用程序中,您的类可能需要与其他可能会或可能不会被编写或测试的类协作,这些类被明确称为依赖项。任何给定的类或系统都可能有自己的依赖项,也可能是其他系统的依赖项。模拟框架适合模拟这些依赖项,而不是模拟被测系统。



For your example, QAService is the main class you're writing (system under test), and QAServiceTest is the unit test for that system. No mocks are necessarily required.

对于您的示例,QAService 是您正在编写的主类(被测系统),而 QAServiceTest 是该系统的单元测试。不一定需要模拟。

Let's say that QAService depends on another class not yet written, called "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. Again, in the unit testcalled QAServiceTest, you use a realQAService and mock its dependencyStorageService.

假设 QAService 依赖于另一个尚未编写的类,称为“StorageService”。在编写 QAService 的测试之前,您不一定要等待 StorageService 工作,因此您使用mock代替使用真正的 StorageService 。同样,在名为 QAServiceTest的单元测试中,您使用真正的QAService 并模拟其依赖项StorageService。

Even though you don't have StorageService written, you probably have some expectation about how QAService will use that class. Maybe you know that when you call storageService.store(qaRecord), it should return a numeric ID like 101. Even without the code working, you can create a Mockito mockStorageService, and prepare it like this:

即使您没有编写 StorageService,您也可能对 QAService 将如何使用该类有一些期望。也许您知道当您调用时storageService.store(qaRecord),它应该返回一个数字 ID,如101. 即使没有代码工作,您也可以创建一个 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). A Mockito mockStorageServicewould check that like this:

现在假设在测试结束时,您要确保您正在测试的 QAService 方法绝对会调用storageService.delete(101). MockitomockStorageService会像这样检查:

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,因为除非被测系统正确调用模拟以获取该返回值(此处为 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. You may not have QAService finished or tested, and using a real QAService would require a StorageService, so instead you use mockQAService with a realQAApplication in your unit testcalled QAApplicationTest.

现在假设您已经编写了另一个名为 QAApplication 的代码块,您正在一个名为 QAApplicationTest 的单元测试中测试它,这取决于 QAService。您可能没有完成或测试 QAService,并且使用真正的 QAService 将需要 StorageService,因此您可以在名为 QAApplicationTest的单元测试中使用带有真实QAApplication 的模拟QAService。



So, to sum up,a mock works withinunit tests to mock the dependenciesof the system under test. In your situation, QAServiceTest will not need a mock QAService, but may be used to mock the dependencies of QAService. If you do need a mock QAService, you'll need it when testing another class where QAService itself is a dependency.

所以,总结一下,一个模拟的作品的单元测试嘲笑依赖的的测试系统。在您的情况下,QAServiceTest 不需要模拟 QAService,但可用于模拟 QAService 的依赖项。如果您确实需要模拟 QAService,则在测试另一个 QAService 本身是依赖项的类时将需要它。