2017-06-12 190 views
2

当我尝试运行我的测试时,出现以下错误。我是新的春季启动,所以不能明白确切的问题。Spring引导Autowired存储库不能与SpringRunner和JPA数据一起工作

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'api.usecase.createtask.CreateTaskTest': Unsatisfied dependency expressed through field 'taskRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'api.usecase.createtask.repository.CreateTaskRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:386) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) 
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'api.usecase.createtask.repository.CreateTaskRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) 
    ... 27 more 

我的单元测试

package api.usecase.createtask; 

import api.model.Task; 
import api.usecase.createtask.contracts.CreateTaskRequest; 
import api.usecase.createtask.contracts.CreateTaskResponse; 
import api.usecase.createtask.repository.CreateTaskRepository; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.junit4.SpringRunner; 

import java.util.List; 

@RunWith(SpringRunner.class) 
public class CreateTaskTest { 

    @Autowired 
    private CreateTaskRepository taskRepository; 

    @Test 
    public void createSuccessfulTask() { 
     CreateTaskRequest createTaskRequest = new CreateTaskRequest(); 
     createTaskRequest.setDescription("Wash car"); 
     createTaskRequest.setAmount(10); 
     createTaskRequest.setRecurrenceType("ONE_OFF"); 
     createTaskRequest.setStatus("NOT_COMPLETED"); 
     CreateTaskResponse createTaskResponse = new CreateTaskResponse(); 
     CreateTask createTask = new CreateTask(this.taskRepository); 
     createTask.handle(createTaskRequest, createTaskResponse); 
     List<Task> tasks = this.taskRepository.findAll(); 
     tasks.forEach(System.out::println); 
    } 
} 

我的仓库类

package api.usecase.createtask.repository; 


import api.model.Task; 
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.stereotype.Repository; 

import java.util.List; 

@Repository 
public interface CreateTaskRepository extends JpaRepository <Task, Long>{ 
    List<Task> findAll(); 
} 

主应用程序文件。我也尝试过使用@EnableJpaRepositories(basePackages = {“api.usecase.createtask.repository”},considerNestedRepositories = true)选项,但仍然无法使用。

package api; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication 
public class Application { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

创建任务的逻辑类

package api.usecase.createtask; 

import api.model.Task; 
import api.usecase.createtask.contracts.CreateTaskRequest; 
import api.usecase.createtask.contracts.CreateTaskResponse; 
import api.usecase.createtask.repository.CreateTaskRepository; 


public class CreateTask { 
    private CreateTaskRepository repository; 

    public CreateTask(CreateTaskRepository repository) { 
     this.repository = repository; 
    } 

    public void handle(CreateTaskRequest createTaskRequest, CreateTaskResponse createTaskResponse) { 
     Task task = new Task(
       createTaskRequest.getDescription(), 
       createTaskRequest.getAmount(), 
       createTaskRequest.getRecurrenceType(), 
       createTaskRequest.getStatus() 
     ); 
     this.repository.save(task); 
    } 
} 

型号

package api.model; 

import org.springframework.stereotype.Component; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name = "CHILD_Tasks") 
public class Task { 
    @Id 
    @Column(name = "id") 
    private long id; 

    @Column(name = "description") 
    private String description; 

    @Column(name = "amount") 
    private float amount; 

    @Column(name = "recurrenceType") 
    private String recurrenceType; 

    @Column(name = "status") 
    private String status; 

    public Task(String description, Float amount, String recurrenceType, String status) { 
     this.description = description; 
     this.amount = amount; 
     this.recurrenceType = recurrenceType; 
     this.status = status; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public long getId() { 
     return this.id; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public String getDescription() { 
     return this.description; 
    } 

    public void setAmount(float amount) { 
     this.amount = amount; 
    } 

    public float getAmount() { 
     return this.amount; 
    } 

    public void setRecurrenceType(String recurrenceType) { 
     this.recurrenceType = recurrenceType; 
    } 

    public String getRecurrenceType() { 
     return this.recurrenceType; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 

    public String getStatus() { 
     return this.status; 
    } 
} 

目录结构

enter image description here

应用程序属性文件

spring.datasource.url=jdbc:mysql://localhost/tasks_db 
spring.datasource.username=root 
spring.datasource.password=root 

spring.jpa.hibernate.ddl-auto=none 
spring.jpa.show-sql = true 
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect 

spring.h2.console.enabled=true 
spring.h2.console.path=/console 
spring.h2.console.settings.trace=false 
spring.h2.console.settings.web-allow-others=false 

的Maven pom.xml文件

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.example</groupId> 
    <artifactId>api</artifactId> 
    <version>2.0</version> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.5.2.RELEASE</version> 
    </parent> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-security</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>io.jsonwebtoken</groupId> 
      <artifactId>jjwt</artifactId> 
      <version>0.7.0</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>info.cukes</groupId> 
      <artifactId>cucumber-java</artifactId> 
      <version>${cucumber.version}</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>info.cukes</groupId> 
      <artifactId>cucumber-spring</artifactId> 
      <version>${cucumber.version}</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>info.cukes</groupId> 
      <artifactId>cucumber-junit</artifactId> 
      <version>${cucumber.version}</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.12</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>com.h2database</groupId> 
      <artifactId>h2</artifactId> 
      <version>1.4.194</version> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>5.2.9.Final</version> 
     </dependency> 

    </dependencies> 

    <properties> 
     <java.version>1.8</java.version> 
     <cucumber.version>1.2.5</cucumber.version> 
    </properties> 

    <distributionManagement> 
     <snapshotRepository> 
      <id>snapshots</id> 
      <url>http://0.0.0.0:8081/nexus/content/repositories/snapshots</url> 
     </snapshotRepository> 
     <repository> 
      <id>releases</id> 
      <url>http://0.0.0.0:8081/nexus/content/repositories/releases</url> 
     </repository> 
    </distributionManagement> 


    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-deploy-plugin</artifactId> 
       <configuration> 
        <skip>true</skip> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.sonatype.plugins</groupId> 
       <artifactId>nexus-staging-maven-plugin</artifactId> 
       <version>1.6.3</version> 
       <executions> 
        <execution> 
         <id>default-deploy</id> 
         <phase>deploy</phase> 
         <goals> 
          <goal>deploy</goal> 
         </goals> 
        </execution> 
       </executions> 
       <configuration> 
        <serverId>nexus</serverId> 
        <nexusUrl>http://0.0.0.0:8081/nexus/</nexusUrl> 
        <skipStaging>true</skipStaging> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 

</project> 
+0

如果您将程序作为启动应用程序启动,是否也会发生这种情况? –

+0

我没有检查过。我只是运行我的测试。 –

+0

我得到java.lang.IllegalArgumentException:至少有一个JPA元模型必须存在!我运行应用程序时出错。 –

回答

1

您还没有指定Spring配置。春天不知道你有什么豆子或在哪里找到它们。

如果您只想测试存储库,则需要添加DataJpaTest注释。文档:http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTest.html

@RunWith(SpringRunner.class) 
@DataJpaTest 
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2) 
public class CreateTaskTest { 
... 

默认情况下,将配置在内存中的嵌入式数据库,扫描 @Entity类和配置Spring数据JPA库。 Regular @ @Component bean不会被加载到ApplicationContext中。

数据JPA测试是事务性和回退在每个测试 的默认端[...]

数据JPA测试也可以注入一个TestEntityManager豆,其提供 到标准JPA的EntityManager替代专门设计 进行测试。如果您想使用 @DataJpaTests之外的TestEntityManager,则还可以使用@AutoConfigureTestEntityManager 注释。 [...]

@RunWith(SpringRunner.class) @DataJpaTest public class ExampleRepositoryTests { 

    @Autowired 
    private TestEntityManager entityManager; 

    @Autowired 
    private UserRepository repository; 

    @Test 
    public void testExample() throws Exception { 
     this.entityManager.persist(new User("sboot", "1234")); 
     User user = this.repository.findByUsername("sboot"); 
     assertThat(user.getUsername()).isEqualTo("sboot"); 
     assertThat(user.getVin()).isEqualTo("1234"); 
    } } 

此外,如果你需要创建一个所有组件豆你可以使用SpringBootTest

我建议你阅读Spring Boot测试参考(link)。 Spring有非常好的文档。

+0

添加JPADataTest和TestEntityManager之后,我得到了:java.lang.IllegalArgumentException:至少必须存在一个JPA元模型!错误。你能给我链接找到更多关于弹簧配置的信息吗?是的,我没有添加它。 –

+0

@shivanshupatel添加弹簧数据jpa依赖关系。 https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa/1.5.4.RELEASE – solomkinmv

+0

@shivanshupatel这里是关于使用spring boot测试的完整文档:https:// docs .spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html – solomkinmv

相关问题