java - 使用 Junit 5 的 RestController unsit 测试中没有名为 'entityManagerFactory' 的 bean

标签 java spring-boot junit mockito junit5

即使我在模拟服务层类,我在 junit5 测试类中也收到“没有名为“entityManagerFactory”的可用 bean”。 我的理解是,如果服务层被模拟,它不应该寻找实际的 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);
  }
}

Controller

@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");
    }
    ..
    
}

Controller 测试类

@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

最佳答案

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

关于java - 使用 Junit 5 的 RestController unsit 测试中没有名为 'entityManagerFactory' 的 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67835094/

相关文章:

java - 下面一行如何生成始终评估为 false 的 Sonar qube 问题?

java - 如何检查文件是否包含用户输入的特定数字? (java)

java - android 可以减少页面数量吗?

docker - 运行基于Spring Boot的docker镜像返回错误信息:Invalid or corrupt jarfile/app. jar

java - Spring Boot spring.datasource.CONFIGURATION_PROPERTIES 无法序列化

testing - TFS 测试结果详细报告与 SoapUI 项目结构不一致

java - Hadoop-伪分布式模式: Input path does not exist

mysql - spring boot 1.5.2 和 EntityScan 有冲突

java - 停止 JUnit 中的参数化测试套件

android - 如何配置 build.gradle 以在具有 Eclipse 文件夹结构的 Android Studio 中进行测试?