Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring MVC控制器测试,并模拟许多类_Java_Spring_Spring Mvc_Mockito - Fatal编程技术网

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

Java Spring MVC控制器测试,并模拟许多类,java,spring,spring-mvc,mockito,Java,Spring,Spring Mvc,Mockito,我们的系统中有许多控制器,还有许多Spring数据存储库 我想为在MVC上下文中运行的控制器编写测试 然而,手工模拟系统中的每个服务和存储库似乎相当麻烦,而且不太合适,这样我就可以测试控制器了 e、 g FooControllerTest.java @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextHierarchy(value = { @ContextConfiguration(classes =

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

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

然而,手工模拟系统中的每个服务和存储库似乎相当麻烦,而且不太合适,这样我就可以测试控制器了

e、 g

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每一个用@Service注释的类或
mock每一个扩展JpaRepository的接口的东西

一个MVC控制器通常被实现为一个将模型与视图集成在一起的粘合代码。例如,当从控制器调用EJB,然后更新视图模型时

因此,当您模拟所有依赖项并验证此集成或“粘合代码”是否按预期工作时,控制器测试可能有意义。一般来说,如果集成测试包含太多组件,那么可能需要对整个sut进行模块化,以使系统真正可测试


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

在控制器测试中,您是否可以简单地执行@Mock YourService服务,并在控制器上设置该服务,并期望/验证模拟的服务?这样,存储库就根本不起作用了(因为这不是您正在测试的anway)
MVCServlet上下文。xml
有一个
组件扫描
,它实例化系统中的所有控制器。控制器将
@Autowire的
连接到各种服务和/或存储库。测试
FooController
仍然需要您模拟
BarService
中使用的
BarController
我已经更新了我的代码片段,但仔细想想,我想要的可能是不可能的。我假设当您说“手动”时,您的意思是在MockServices中添加一个额外的方法。我不认为这是一个巨大的开销(只要你的测试为你工作)。然而,我只需关注控制器,而不必担心WebAppConfiguration、xml等(并不是说您的方法是错误的),就可以保持这种状态。您可以在控制器测试中简单地@Mock YourService服务,而不是编写和更新MockServices。如果设置服务有问题,可以自动连接接收服务的控制器构造函数。希望有帮助!您可以使用不同的模拟工具JMockit(我开发的)来完成所需的工作。您只需要声明注释为
@Capturing
的模拟字段,这样Spring实例化的实现类就可以得到模拟。