Spring Boot Controller Test:需要下游对象的模拟服务,导致ApplicationContext无法加载

问题描述 投票:1回答:2

我试图用Mock运行一个控制器级的Spring Boot单元测试,用于我的服务层依赖。但是,这个Mock需要一个使用EntityManager对象的下游存储库依赖项,这会导致我的测试在加载ApplicationContext时失败。

我的测试不涉及存储库依赖项或EntityManager,它使用Mocked服务对象返回一个预设响应。如果我只想模拟服务层对象,为什么Spring会抱怨repo / EntityManager

控制器单元测试代码:

@RunWith(SpringRunner.class)
@WebMvcTest
@AutoConfigureWebClient
public class MobileWearControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    UserDeviceService userDeviceService;

    //.....
}

UserDeviceService代码:

@Service
public class UserDeviceService {

    private UserDeviceRepository userDeviceRepository;

    public UserDeviceService(UserDeviceRepository userDeviceRepository) {
        this.userDeviceRepository = userDeviceRepository;
    }

    //....
}

UserDeviceRepository代码:

@Repository
public class UserDeviceRepositoryImpl implements UserDeviceRepositoryCustom {

    @PersistenceContext
    private EntityManager em;

    //....
}

期待测试运行。

实际结果是获得以下堆栈跟踪:

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDeviceRepositoryImpl': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
...

spring unit-testing spring-boot jpa entitymanager
2个回答
1
投票

我的问题是我用于测试的注释。

使用@AutoConfigureWebClient尝试站起来整个Spring Context;因为我是单元测试我的控制器,我想只测试web层并模拟下游依赖项(即UserDeviceService)。所以,我应该使用@SpringBootTest和@AutoConfigureMockMvc,它将仅为控制器层设置我的Spring上下文。

使用这种方法,我能够成功地模拟UserDeviceService,从而允许我的测试编译和运行:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MobileWearControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    UserDeviceService userDeviceService;

    //...
}

0
投票

首先,您需要指定要测试的控制器

@WebMvcTest(YourController.class)

此外,使用JUnit5,您不需要配置任何扩展,因为@WebMvcTest包含@ExtendWith(SpringExtension.class)。你显然是在JUnit4上,但这不应该造成任何伤害。

检查例如https://spring.io/guides/gs/testing-web/

© www.soinside.com 2019 - 2024. All rights reserved.