解释一下Java中的@Mock和@Spy? [重复]

问题描述 投票:0回答:1

我最近开始学习单元测试,并遇到了 Mockito 库。我读到了 @Mock 和 @Spy when() 等..

@Mock
Service service;

@Test
void test(){
   when(service.runCode(Mock.anyString()).thenReturn("Working");
}

我在上面一行中的疑问是,

runCode(String a)
是否会被执行,或者一旦调用该方法,那么我在
thenReturn()
部分中给出的内容将由模拟返回?

我正在尝试理解模拟

mockito junit5
1个回答
0
投票

由于您是单元测试的新手,我将编写一个关于

Mocks
如何工作的简化说明。首先,重要的是要了解
dummies
fakes
mocks
spies
只是不同类型的测试对象,它们看起来像您在生产中使用的实际对象。它们可以注入到您想要测试的组件中,以验证交互和/或返回一些测试数据。

要了解mockito在幕后做什么,您可以首先尝试基于公共接口编写自己的模拟:

public interface Service {
    String runCode(String arg);
}

例如,您可以创建此 Service 接口的测试实现,无论传入的参数如何,它都将始终返回相同的硬编码值。这将是一个 Dummy:

public class DummyService implements Service {
    @Override
    public String runCode(String arg) {
        return "dummy_response";
    }
}

因此,您将能够在测试中使用它来避免运行实际的

runCode
方法。假设您有一个要测试的
Controller
类,该类在内部使用此
Service
,测试将如下所示:

@Test
void test() {
    Controller c = new Controller(new DummyService());
    var response = c.doSomething("abc");
    // assert response ...
}

如您所见,虚拟对象相当“愚蠢”。有时您可能希望能够根据方法的输入返回不同的字符串。在这种情况下,您可以创建自己的Mock public class MockedService implements Service { private Map<String, String> mockedData = new HashMap<>(); public void whenRunCodeThenReturn(String arg, String mockedResponse) { mockedData.put(arg, mockedResponse); } @Override public String runCode(String arg) { return mockedData.get(arg); } }

现在,您必须实例化 
MockedService

并根据测试的需要指定一些行为:

@Test
void test() {
    MockedService mock = new MockedService();
    Controller c = new Controller(mock);
    mock.whenRunCodeThenReturn("abc", "mocked_response_for_abc");
    
    var response = c.doSomething("abc");
    // assert response ...
}

当然,
mockito

是一个强大的框架,提供了更多的灵活性。它具有允许您为输入参数定义更复杂的条件的功能,它可以在每次测试后轻松重置模拟,并且不需要公共接口来代理对象。 有关假货、间谍和模拟等测试对象的更详细说明,请查看这篇文章:

https://medium.com/gitconnected/the-anatomy-of-mocks-in-unit-testing-3e6a78b2b5d3

如果您想更深入地了解该框架,这里是他们的文档:

https://site.mockito.org/

© www.soinside.com 2019 - 2024. All rights reserved.