我有一个主要的@SpringBootApplication
,它需要扫描特定的软件包才能启用JPA存储库,因此我使用@EnableJpaRepositories
来指定。现在,我正在实施单元测试,并且只想测试Controller组件,因此我遵循了官方文档中的教程,在该教程中,他们使用@WebMvcTest(MyController.class)
来测试具有服务依赖性的控制器。
问题是这对我不起作用,因为它试图加载我在主Spring Boot应用程序中指定的JpaRepositories(当我在主类中评论@EnableJpaRepositories
时,测试运行没有问题)。>
我猜我需要为测试类创建一个特定的配置,以便它可以忽略主要配置(因为我只想加载Controller并模拟服务层),但是我不知道如何创建这样。我尝试添加一个空配置,但仍然失败,并显示相同错误:
@TestConfiguration
static class TestConfig {}
这是我得到的错误:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'failureTaskHandler': Unsatisfied dependency expressed through field 'myManager'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'msgManager': Unsatisfied dependency expressed through field 'inboundManager'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inboundManager': Unsatisfied dependency expressed through field 'messageRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageRepository' defined in com.example.MessageRepository defined in @EnableJpaRepositories declared on MonitorApplication: Cannot create inner bean '(inner bean)#45e639ee' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#45e639ee': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
我的测试班:
@WebMvcTest(MyController.class)
public class MyControllerTest {
@Autowired private MockMvc mvc;
@MockBean private MyService service;
// Tests here
// @Test
// public void...
}
MyController类:
@RestController
@CrossOrigin
@RequestMapping("/api")
@Slf4j
public class MyController {
@Autowired private MyService service;
@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody SearchResponse getOrders(@RequestBody SearchRequest orderSearchRequest) {
log.info("Receiving orders request...");
return service.getOrders(orderSearchRequest);
}
}
答案 0 :(得分:0)
声明单独的配置
@Configuration
@EnableJpaRepositories
public class DataConfiguration { ... }
将其导入应用程序
@SpringBootApplication
@Import({ DataConfiguration.class })
public class MainApplication { ... }
但不要导入MyControllerTest
答案 1 :(得分:0)
快速解决方案
从您的 Spring Boot 应用程序类中删除 @EnableJpaRepositories
。使用:
@SpringBootApplication
public class MainApplication {
}
代替
@SpringBootApplication
@EnableJpaRepositories
public class MainApplication {
}
在这种情况下,Spring Boot 将在类路径上找到 Spring Data JPA,并使用自动配置来扫描存储库的包。
使用 @EnableJpaRepositories
扫描特定包
使用带有单独配置的@NikolaiShevchenko 解决方案,但不显式导入它(因为测试也会显式导入配置)并让 Spring Boot 在包扫描期间找到您的配置。
@SpringBootApplication
public class MainApplication {
}
@Configuration
@EnableJpaRepositories(basePackages = "com.app.entities")
public class JpaConfig {
}
重要
如果您将配置放在单独的包中,请不要忘记添加 basePackages
属性。