如何忽略测试方法内部的交互

时间:2019-11-13 18:35:15

标签: spring spring-boot junit junit5

所以我有一个复杂的rest控制器,我想忽略实现,而只关注授权方面。

@RestController
public class SettingsController {

    private final Service1
    private final Service2
    private final Service3
    private final Service4

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("settings")
    ResponseEntity subgrups() {
        //impl using a service1/service2/service3/service4
    }

}

由于我只想测试授权,因此我正在寻找这样的测试:

@WebMvcTest(controllers = SettingsController.class)
public class SettingsControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(role="ADMIN")
    public void whenSearchingForGroupAndHasAccessToPolicy() throws Exception {
        mockMvc.perform(get("/settins"))
                .andExpect(status().isOk());
    }
}

但是由于我有很多互动,我的测试看起来像

@WebMvcTest(controllers = SettingsController.class)
public class SettingsControllerTest {

    //mock service1

    //mock service2

    //mock service3

    //mock service4

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(role="ADMIN")
    public void whenSearchingForGroupAndHasAccessToPolicy() throws Exception {
        //build some mock for service1
        //mock interaction service1
        //build some mock for service2
        //mock interaction service2
        //build some mock for service3
        //mock interaction service3
        //build some mock for service4
        //mock interaction service4

        mockMvc.perform(get("/settins"))
                .andExpect(status().isOk());
    }
}

是否有任何模式可以清理这种混乱状况?

1 个答案:

答案 0 :(得分:3)

似乎更多的是设计问题。控制器应尽可能薄。您的控制器应委派给执行所有必要业务逻辑的单个服务。该服务将引用执行该逻辑所需的其他服务。

然后,您只需要模拟该单一服务即可。

https://imgur.com/a/KbVrIHr

@WebMvcTest(controllers = SettingsController.class)
@MockBean(classes = {SettingsService.class})
public class SettingsControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(role="ADMIN")
    public void whenSearchingForGroupAndHasAccessToPolicy() throws Exception {
        mockMvc.perform(get("/settins"))
                .andExpect(status().isOk());
    }
}