我在junit 5测试类中得到“No bean named 'entityManagerFactory' available”,即使我在模拟服务层类时也是如此。我的理解是,如果服务层被模拟,它不应该寻找实际的jpa实现。我不明白我错过了什么。我的应用程序在JPA中运行良好,唯一的问题是我在使用@WebMvcTest进行单元测试时遇到的问题
spring Boot 应用类
@SpringBootApplication(
scanBasePackages = {"com.testapp.rest.auth"})
@EnableJpaRepositories
public class SampleAuthorizationServiceApplication {
public static void main(String[] args) {
SpringApplication.run(SampleAuthorizationServiceApplication.class, args);
}
}
控制器
@PostMapping(
value = "/testRest/auth",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResObj> testValid(
@RequestBody ReqObj reqObj, @RequestHeader HttpHeaders headerSet)
throws SampleTechnicalException {
ResObj response = authServ.authorize(reqObj);
if (response.isSuccess()) {
log.info("Request processed successfully. response : {}", response.isSuccess());
return ResponseEntity.ok(response);
} else {
log.error(
"Request couldn't be processed successfully. response : {}",
response.isSuccess());
return new ResponseEntity<ResObj>(response, HttpStatus.UNAUTHORIZED);
}
}
服务
@Service
@AllArgsConstructor
@Slf4j
public class AuthSerive {
private SampleRepository1 sampleRepository1;
private SampleRepository2 sampleRepository2;
public ResObj authorize(ReqObj reqObj) throws SampleTechnicalException {
if (reqObj == null) {
throw new SampleTechnicalException("throw exception");
}
..
}
控制器测试类
@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = AuthController.class)
class AuthControllerTest {
@MockBean AuthSerive authServ;
@Autowired private MockMvc mockMvc;
@Test
void testAuthSample() throws Exception {
String jsonreq =
"{ \"field1\":\"\", \"field2\":\"x\", \"field3\":\"\", \"field4\":\"\", \"field5\":"y", \"field6\":\"z\", \"field7\":\"x\" }";
ResObj mockResponse =
ResObj.builder().authSuccess(true).errorMessage(null).build();
ReqObj mockTestObj=
ReqObj.builder().field2("x").field5("y").field6("z").field7("x").build();
Mockito.when(authServ.authorize(mockTestObj)).thenReturn(mockResponse);
mockMvc
.perform(post("/api/testRest/auth").contentType("application/json").content(jsonreq))
.andExpect(status().isOk());
}
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
implementation 'com.oracle.database.jdbc:ojdbc8:18.3.0.0'
compileOnly 'org.projectlombok:lombok:1.18.4'
annotationProcessor 'org.projectlombok:lombok'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.5.8'
implementation group: 'org.springframework', name: 'spring-context'
testCompile ("org.springframework.boot:spring-boot-starter-test") {
exclude group: "org.mockito", module: "mockito-all"
}
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
错误
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SampleRepository1' defined in com.testapp.rest.auth.repository.SampleRepository1 defined in @EnableJpaRepositories declared on SampleAuthorizationServiceApplication: Cannot create inner bean '(inner bean)#47a7c93e' 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)#47a7c93e': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:389)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1689)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1434)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:925)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:339)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:123)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
... 68 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#47a7c93e': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:693)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:374)
... 87 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
2条答案
按热度按时间7dl7o3gd1#
我理解这个问题是因为@EnableJpaRepositories是与bootapllication类,它试图加载它。解决方案是bootapplication类应该只有@springbootapplication注解,任何其他配置都可以移动到带有@configuration注解的单独配置文件。我在这里找到了Spring @WebMvcTest with @EnableJpa* annotation
92dk7w1h2#
在我这边,只添加
@EnableAutoConfiguration
就解决了这个问题。