当前位置: 首页 > 知识库问答 >
问题:

添加多个服务时,Springboot集成测试失败

丁文轩
2023-03-14

我有一个SpringBoot应用程序,它有一个控制器类、一个服务和一个存储库,运行得非常好。我已经为相同的应用程序添加了Junit测试用例,而且效果也非常好。

@RestController
public class EmployeeController{
    @Autowired
    EmployeeService service;

    @GetMapping("/list")
    public List<Employee> getEmployee(){
       return service.findAll();
    }
}


@Service
public class EmployeeService{
   
   @Autowired
   EmployeeRepository repository;

   public List<Employee> findAll(){
      return repository.findAll();
   }
}

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, String>{}

下面是测试类。

@RunWith(SpringRunner.class)
@WebMvcTest(value = EmployeeController.class)
class EmployeeControllerIntegrationTest {
    @Autowired
    private MockMvc mvc;

    @MockBean
    private EmployeeService service;

    @Test
    public void findAllEmployeeTest(){
    }
}

测试用例一直通过,但目前我正在添加另一个API,如下所示,所有测试都失败了。

@RestController
public class DepartmentController{
    @Autowired
    DepartmentService service;

    @GetMapping("/list")
    public List<Department> getDepartment(){
       return service.findAll();
    }
}


@Service
public class DepartmentService{
   
   @Autowired
   DepartmentRepository repository;

   public List<Department> findAll(){
      return repository.findAll();
   }
}
@Repository
public interface DepartmentRepository extends JpaRepository<Department, String>{}

下面是测试类。

@RunWith(SpringRunner.class)
@WebMvcTest(value = DepartmentController.class)
class DepartmentControllerIntegrationTest {
    @Autowired
    private MockMvc mvc;

    @MockBean
    private DepartmentService service;

    @Test
    public void findAllDepartmentTest(){
    }
}

添加部门服务后,测试用例失败,错误如下:

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'departmentController': Unsatisfied dependency expressed through field 'departmentService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'departmentService': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.employeeapp.data.repository.DepartmentRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

干杯!

共有2个答案

慕阳平
2023-03-14

没有可用的com.employeeapp.data.repository.DepartmentRepository类型的限定bean:预期至少有1个bean有资格作为自动连接候选。

Spring查找TYPE的bean:DepartmentRepository

  1. 定义Bean
@Repository
public interface DepartmentRepository extends JpaRepository<Department, String>{}

在这里添加注释@Repository,这样Spring就可以将DepartmentRepository转换为Bean。

java prettyprint-override">@Service
public class DepartmentService{
   
   @Autowired
   private DepartmentRepository repository; // The best practice is to write the full bean name here departmentRepository.

   public List<Department> findAll(){
      return repository.findAll();
   }
}

淳于鹏
2023-03-14

据我所见,您试图通过模仿您的服务来进行IT测试。在IT测试中,您不会嘲笑您的服务。在集成测试中,您测试所有组件是否协同工作。如果您不模拟存储库,那么它更像是一个E2E测试(端到端测试所有交互路径)。

如果没有要测试的逻辑和/或不想在数据库中写入,则可以模拟存储库。

因此,如果是单元测试,您可以尝试(它在我的项目中工作),我使用JUnit5(org.Junit.jupiter)


    @WebMvcTest(DepartementController.class)
    public class DepartementControllerTest {
    
      @MockBean
      private DepartmentService departmentService;
    
    
      @Autowired
      MockMvc mockMvc;
    
    @Test
    public void findAllTest(){
     // You can create a list for the mock to return
    when(departmentService.findAll()).thenReturn(anyList<>);
    
    //check if the controller return something
    assertNotNull(departmentController.findAll());
    
    //you check if the controller call the service
    Mockito.verify(departmentService, Mockito.times(1)).findAll(anyList());
    }

那是单元测试。

It测试更像是


    @ExtendWith(SpringExtension.class)
    @SpringBootTest
    public class DepartmentIT {
    
    
      @Autowired
      DepartmentService departmentService;
    
      @Autowired
      private WebApplicationContext wac;
    
      private MockMvc mockMvc;
    
      @BeforeEach
      void setUp() {
        this.mockMvc =
                MockMvcBuilders.webAppContextSetup(this.wac)
                        .build();
      }
    
      @Test
      void departmentFindAll() throws Exception {
        MvcResult mvcResult = this.mockMvc.perform(get("/YOUR_CONTROLLER_URL")
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().is(200))
                .andReturn();
    
        
assertTrue(mvcResult.getResponse().getContentAsString().contains("SOMETHING_EXPECTED"));
        assertTrue(mvcResult.getResponse().getContentAsString().contains("SOMETHING_EXPECTED"));
        assertTrue(mvcResult.getResponse().getContentAsString().contains("SOMETHING_EXPECTED"));
    
    //You also can check its not an empty list, no errors are thrown etc...
    
      }

进口使用,所以你不会搜索太多


import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

 类似资料:
  • 我正在尝试如何在使用Eureka的Spring Boot应用程序上构建集成测试。说我有考试 我的代码路径中有该 api 调用: 这将NPE。发现客户端返回为空。如果我直接启动 Spring 启动应用程序并自己使用 API,代码工作正常。我在任何地方都没有特定的个人资料用法。我需要为发现客户端配置一些特殊的 wrt Eureka 以进行测试吗?

  • 我正在使用一个带有spring boot 2.0.0.rc1的多项目分级器。我的子项目之一是SpringBoot应用程序,其中包含了我的集成测试。 集成测试用WebEnvironment.random_port标记为@springboottest。由于未解析的依赖关系(在另一个子项目中声明的服务,的同级),测试失败,使用了gradle命令行,但在Eclipse IDE中成功。 如果有人有主意?如何

  • 我有几个繁重的Spring集成测试(是的,这不是最好的方法,我没有时间正确地模拟所有外部dep) 下面是测试的典型注释 由于以下原因,测试会定期失败: 这里有两个问题:1、让测试共存的正确方式是什么?我在surefire插件中设置了forkCount=0。好像有帮助 2.1. 在每次测试期间,我实际上不需要启动所有的

  • 我正在使用Spring引导 1.3 开发一个 spring 应用程序 我有一个类似这样的MVC请求处理程序: 这是它的集成测试 删除了一些位以留出空间,但请注意顶部的@Transactional注释 它运行和通过没有线: 但是当添加它时,它给出了这个讨厌的异常,这是一个bean验证异常,没有任何数据插入操作(Spring mvc已经处理的验证错误和BindingResault中的结果) 当我在类级

  • 我从不编写集成测试,不明白我做错了什么?会是什么问题?按照我的理解,我应该像这样添加@componentscan或smth?