Spring MVC控制器测试,并模拟了许多类



我们的系统中有许多控制器和许多Spring数据存储库。

我想为运行在MVC上下文中的控制器编写测试。

然而,必须手动模拟系统中的每个服务和存储库,这样我就可以测试控制器,这似乎很麻烦,而且是不对的

例如

FooControllerTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy(value = {
    @ContextConfiguration(classes = { MockServices.class }),
    @ContextConfiguration({ "classpath:/META-INF/spring/mvc-servlet-context.xml" }),
})
public class FooControllerTest {
    @Autowired
    private WebApplicationContext wac;
    private MockMvc mvc;
    @Autowired
    private FooRepository fooRepository;
    @Autowired
    private FooService fooService; 
    @Before
    public void setUp() throws Exception {
        mvc = webAppContextSetup(wac).build();
    }
    @Test
    public final void list() {
        when(fooRepository.findAll()).thenReturn(...);
        mvc.perform(get("/foo"))...
    }
    @Test
    public final void create() {
        Foo fixture = ...
        when(fooService.create(fixture)).thenReturn(...);
        mvc.perform(post("/foo"))...
    }
}

MockServices.java

@Configuration
public class MockServices {
    @Bean
    public FooRespository fooRepositiory() {
        return Mockito.mock(FooRespository.class);
    }
    @Bean
    public FooService fooService() {
        return Mockito.mock(FooService.class);
    }
    //even though we are "only" testing FooController, we still need to mock BarController's dependencies, because BarController is loaded by the web app context.
    @Bean
    public BarService barService() {
        return Mockito.mock(FooService.class);
    }
    //many more "mocks"
}

我真的不想使用standaloneSetup()(想使用生产配置,例如转换服务、错误处理程序等)

这只是我写控制器测试的代价吗?

似乎应该有类似mock every class annotated with @Servicemock every interface that extends JpaRepository

MVC控制器的实现通常类似于将模型与视图集成的粘合代码。例如,当从控制器调用EJB,然后更新视图模型时。

因此,当您模拟所有依赖项并验证此集成或"粘合代码"是否按预期工作时,控制器测试可能会有意义。一般来说,如果集成测试意味着太多的组件,那么整个sut的模块化可能是系统真正可测试的必要条件。

无论如何,如果您觉得集成测试很费力,也许您可以尝试获得每个独立组件的最大覆盖率,并让功能测试获得Controller覆盖率。

相关内容

  • 没有找到相关文章

最新更新