How to make instance of CrudRepository interface during testing in Spring?

后端 未结 4 1006
旧时难觅i
旧时难觅i 2021-02-07 08:53

I have a Spring application and in it I do not use xml configuration, only Java Config. Everything is OK, but when I try to test it I faced problems wi

相关标签:
4条回答
  • 2021-02-07 09:01

    You cant use repositories in your configuration class because from configuration classes it finds all its repositories using @EnableJpaRepositories.

    1. So change your Java Configuration to:
    @Configuration
    @EnableWebMvc
    @EnableTransactionManagement
    @ComponentScan("com.example")
    @EnableJpaRepositories(basePackages={"com.example.jpa.repositories"})//Path of your CRUD repositories package
    @PropertySource("classpath:application.properties")
    public class JPAConfiguration {
      //Includes jpaProperties(), jpaVendorAdapter(), transactionManager(), entityManagerFactory(), localContainerEntityManagerFactoryBean()
      //and dataSource()  
    }
    
    1. If you have many repository implementation classes then create a separate class like below
    @Service
    public class RepositoryImpl {
       @Autowired
       private UserRepositoryImpl userService;
    }
    
    1. In your controller Autowire to RepositoryImpl and from there you can access all your repository implementation classes.
    @Autowired
    RepositoryImpl repository;
    

    Usage:

    repository.getUserService().findUserByUserName(userName);

    Remove @Repository Annotation in ArticleRepository and ArticleServiceImpl should implement ArticleRepository not ArticleService.

    0 讨论(0)
  • 2021-02-07 09:03

    If you're using Spring Boot, you can simplify these approaches a bit by adding @SpringBootTest to load in your ApplicationContext. This allows you to autowire in your spring-data repositories. Be sure to add @RunWith(SpringRunner.class) so the spring-specific annotations are picked up:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class OrphanManagementTest {
    
      @Autowired
      private UserRepository userRepository;
    
      @Test
      public void saveTest() {
        User user = new User("Tom");
        userRepository.save(user);
        Assert.assertNotNull(userRepository.findOne("Tom"));
      }
    }
    

    You can read more about testing in spring boot in their docs.

    0 讨论(0)
  • 2021-02-07 09:18

    What you need to do is:

    1. remove @Repository from ArticleRepository

    2. add @EnableJpaRepositories to PagesTestConfiguration.java

      @Configuration
      @ComponentScan(basePackages = {"com.example.core"}) // are you sure you wanna scan all the packages?
      @EnableJpaRepositories(basePackageClasses = ArticleRepository.class) // assuming you have all the spring data repo in the same package.
      public class PagesTestConfiguration {
      
      @Bean
      public ArticleServiceImpl articleServiceImpl() {
          ArticleServiceImpl articleServiceImpl = new ArticleServiceImpl();
          return articleServiceImpl;
      }
      }
      
    0 讨论(0)
  • 2021-02-07 09:21

    This is what I have found is the minimal setup for a spring controller test which needs an autowired JPA repository configuration (using spring-boot 1.2 with embedded spring 4.1.4.RELEASE, DbUnit 2.4.8).

    The test runs against a embedded HSQL DB which is auto-populated by an xml data file on test start.

    The test class:

    @RunWith( SpringJUnit4ClassRunner.class )
    @ContextConfiguration( classes = { TestController.class,
                                       RepoFactory4Test.class } )
    @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
                               DirtiesContextTestExecutionListener.class,
                               TransactionDbUnitTestExecutionListener.class } )
    @DatabaseSetup( "classpath:FillTestData.xml" )
    @DatabaseTearDown( "classpath:DbClean.xml" )
    public class ControllerWithRepositoryTest
    {
        @Autowired
        private TestController myClassUnderTest;
    
        @Test
        public void test()
        {
            Iterable<EUser> list = myClassUnderTest.findAll();
    
            if ( list == null || !list.iterator().hasNext() )
            {
                Assert.fail( "No users found" );
            }
            else
            {
                for ( EUser eUser : list )
                {
                    System.out.println( "Found user: " + eUser );
                }
            }
        }
    
        @Component
        static class TestController
        {
            @Autowired
            private UserRepository myUserRepo;
    
            /**
             * @return
             */
            public Iterable<EUser> findAll()
            {
                return myUserRepo.findAll();
            }
        }
    }
    

    Notes:

    • @ContextConfiguration annotation which only includes the embedded TestController and the JPA configuration class RepoFactory4Test.

    • The @TestExecutionListeners annotation is needed in order that the subsequent annotations @DatabaseSetup and @DatabaseTearDown have effect

    The referenced configuration class:

    @Configuration
    @EnableJpaRepositories( basePackageClasses = UserRepository.class )
    public class RepoFactory4Test
    {
        @Bean
        public DataSource dataSource()
        {
            EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
            return builder.setType( EmbeddedDatabaseType.HSQL ).build();
        }
    
        @Bean
        public EntityManagerFactory entityManagerFactory()
        {
            HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            vendorAdapter.setGenerateDdl( true );
    
            LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
            factory.setJpaVendorAdapter( vendorAdapter );
            factory.setPackagesToScan( EUser.class.getPackage().getName() );
            factory.setDataSource( dataSource() );
            factory.afterPropertiesSet();
    
            return factory.getObject();
        }
    
        @Bean
        public PlatformTransactionManager transactionManager()
        {
            JpaTransactionManager txManager = new JpaTransactionManager();
            txManager.setEntityManagerFactory( entityManagerFactory() );
            return txManager;
        }
    }
    

    The UserRepository is a simple interface:

    public interface UserRepository extends CrudRepository<EUser, Long>
    {
    }   
    

    The EUser is a simple @Entity annotated class:

    @Entity
    @Table(name = "user")
    public class EUser
    {
        @Id
        @Column(name = "id")
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Max( value=Integer.MAX_VALUE )
        private Long myId;
    
        @Column(name = "email")
        @Size(max=64)
        @NotNull
        private String myEmail;
    
        ...
    }
    

    The FillTestData.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <dataset>
        <user id="1"
              email="alice@test.org"
              ...
        />
    </dataset>
    

    The DbClean.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <dataset>
        <user />
    </dataset>
    
    0 讨论(0)
提交回复
热议问题