java RestController unsit test with Junit 5中没有名为“entityManagerFactory”的bean可用

ut6juiuv  于 2023-04-10  发布在  Java
关注(0)|答案(2)|浏览(105)

我在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
7dl7o3gd

7dl7o3gd1#

我理解这个问题是因为@EnableJpaRepositories是与bootapllication类,它试图加载它。解决方案是bootapplication类应该只有@springbootapplication注解,任何其他配置都可以移动到带有@configuration注解的单独配置文件。我在这里找到了Spring @WebMvcTest with @EnableJpa* annotation

92dk7w1h

92dk7w1h2#

在我这边,只添加@EnableAutoConfiguration就解决了这个问题。

相关问题