Spring Mockito-Junit控制器测试-模拟一项服务

时间:2019-02-05 16:09:15

标签: java spring spring-boot

我有一个控制器类 ControllerClass ,它管理两个类服务:

    解析某些文件的
  • ServiceA

  • ServiceB ,用于管理文件系统

我想测试 ControllerClass ,尤其是:

  • ServiceA 自动接线类

  • ServiceB 模拟该服务,其中包含一个模拟类,该类实现了始终返回固定值的界面。

我该怎么办?

2 个答案:

答案 0 :(得分:2)

@MockBean看起来很适合您的用例。

此注释的行为如下:

  • 如果在测试上下文中未定义任何bean,则将添加新的
  • 如果已经定义了单个bean,则它将替换为 模拟
  • 如果已经定义了两个或多个bean,则使用@Qualifier 指定应该用模拟代替哪一个

在您的测试类中连接了模拟bean之后,可以将其存根以始终返回一些值。例如,对于特定测试,只需在测试中添加以下内容即可:

    @Autowired
    private ServiceA serviceA;
    @MockBean
    private ServiceB serviceB;

    @Test
    public void testSomething() {
        when(serviceB.doSomething()).thenReturn("fixed response");
        // ...
    }

如果要对所有测试都进行存根-将存根放入设置方法:

    @Autowired
    private ServiceA serviceA;
    @MockBean 
    private ServiceB serviceB;

    @Before
    public void setup() {
        when(serviceB.doSomething()).thenReturn("fixed response");
    }

顺便说一句,Spring还证明@SpyBean的行为与@MockBean类似。

如果对它们进行方法调用存根,则间谍和模拟之间基本上没有区别。当方法调用未加桩时,差异会变得明显:

  • 在模拟的情况下-不执行任何操作(如果方法返回void-只是不被调用,如果方法返回某些内容-那么模拟将返回 null
  • 如果是间谍-调用实物方法。

答案 1 :(得分:1)

从一个简单的spring-web应用程序开始,进行以下测试:

tcpping

解决方案I

使用@MockBean和@Before:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MyControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void testGreeting() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("A response: I am real ServiceA!, B response: I am real ServiceB!")));
    }
}

解决方案II

使用弹簧轮廓和自定义测试配置:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MyControllerMockBeanTest {

    @MockBean
    private ServiceB mockB;

    @Before
    public void setup() {
       Mockito.when(mockB.greeting()).thenReturn("I am mock Service B!");
    }
    @Autowired
    private MockMvc mvc;

    @Test
    public void testGreetingMock() throws Exception {
       mvc.perform(MockMvcRequestBuilders.get("/")
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().string(equalTo("A response: I am real ServiceA!, B response: I am mock Service B!")));
    }
}

Complete sample at github.


我非常确定,解决方案列表不完整。

...