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



我有一个spring-boot应用程序,它有一个控制器类、一个服务和一个存储库,工作非常好。我添加了同样的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)}

干杯!

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

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

因此,如果是单元测试,你可以尝试(它适用于我的项目(,我使用Junit 5(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;

No qualifying bean of type 'com.employeeapp.data.repository.DepartmentRepository' available: expected at least 1 bean which qualifies as autowire candidate.

Spring查找TYPE:DepartmentRepository的bean。

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

在这里添加注释@Repository,这样Spring就可以将DepartmentRepository变成Bean。

  1. 自动连接正确的类型和名称
@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();
}
}

最新更新