Java 测试web层Spring引导

Java 测试web层Spring引导,java,spring,testing,Java,Spring,Testing,刚刚在Spring Boot中制作了一个控制器,我想对它进行单元测试 控制器及其方法的代码为: @Controller @RequestMapping("/projects/{pid}/clusters") public class ClusterController { @Autowired private ClusterService clusterService; @Autowired private ProjectService projectServ

刚刚在Spring Boot中制作了一个控制器,我想对它进行单元测试

控制器及其方法的代码为:

@Controller
@RequestMapping("/projects/{pid}/clusters")
public class ClusterController {

    @Autowired
    private ClusterService clusterService;

    @Autowired
    private ProjectService projectService;


    @RequestMapping(method = RequestMethod.GET)
    public String getAllClusters(@PathVariable("pid") Integer projectId, Model model){
        Project project = this.projectService.getProjectById(projectId);
        Set<Cluster> clusters = project.getClusters();
        model.addAttribute("projectID", projectId);
        model.addAttribute("clusters", clusters);
        return "clusters";
    }
使用其中一条注释的建议来测试它并获取返回类型。
但在我的控制器类中,我给出了模型作为参数。我如何在测试中给控制器这个?简单地将模型建模为参数是行不通的。

我建议使用MockMvc或restasured来测试Web层

MockMvc:

MockMvc的示例:

重新发行:

重新担保的示例:


通过验证控制器的方法是否返回特定视图的名称,您并不是在测试web层的集成级别,而是测试SpringMVC工作原理的实现细节

如果要进行适当的web级测试,可以测试结果的某些属性,这些属性足以验证页面创建逻辑是否有效,例如,包含某些特定字符串:

// (...)
assertThat(response.getBody(), contains("\"clusters\""));
或者使用JsonPath验证JSON级别的内容,验证结构和/或值本身

依赖项,即已经在其他地方测试过的服务和存储库,应该进行模拟,例如使用方便的注释

如果您确实希望验证控制器是否在代码级别工作,而代码级别不会增加太多价值,则可以将测试简化为:

@RunWith(MockitoRunner.class)
public class clusterControllerTest {
    // inject any dependencies as mocks
    ClusterController testee = new ClusterController();

    @Test
    public void getCluster() {
        String returnedViewName = testee.getCluster();
        assertThat(returnedViewName).isEqualTo("clusters"));
        // Hurray, it worked, but does it verify anything? Nope.
    }
}

我已经在第一个链接中查看了MockMvc并尝试了它。然后它会给我错误,因为我的集群实体与其他实体有一些关系,并且正在使用LazyLoading。我看到了你的想法和我的想法,以及它们的区别。但正如我所说,我已经在测试所有其他层,如回购和服务。我所有的控制器方法都只是从被测试的服务层调用方法。在我的情况下,测试什么更有意义?您可以使用Mockito和对依赖项的内部调用,但这不是一个好的控制器测试-一旦更改了实现,它就会中断,即使控制器的HTTP响应没有更改,换句话说,测试控制器级别没有多大意义?因为我的项目中唯一的任务就是调用其他层中的方法
// (...)
assertThat(response.getBody(), contains("\"clusters\""));
@RunWith(MockitoRunner.class)
public class clusterControllerTest {
    // inject any dependencies as mocks
    ClusterController testee = new ClusterController();

    @Test
    public void getCluster() {
        String returnedViewName = testee.getCluster();
        assertThat(returnedViewName).isEqualTo("clusters"));
        // Hurray, it worked, but does it verify anything? Nope.
    }
}