簡體   English   中英

如何加載應用程序上下文以使用 JUnit 4 測試 Spring 應用程序?

[英]How to load application context for testing Spring application with JUnit 4?

I have a Spring application ( not Spring Boot) where I use Spring Data JPA and annotation based Java configuration. 我正在嘗試對創建自定義保存方法的存儲庫片段(JUnit 4)進行單元測試,但我無法正確加載所需的上下文和 bean 來運行測試:

[main] INFO org.springframework.test.context.support.DefaultTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener]
[main] INFO org.springframework.test.context.support.DefaultTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@87f383f, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@4eb7f003, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@eafc191, org.springframework.test.context.support.DirtiesContextTestExecutionListener@612fc6eb, org.springframework.test.context.transaction.TransactionalTestExecutionListener@1060b431, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@612679d6, org.springframework.test.context.event.EventPublishingTestExecutionListener@11758f2a]
[main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
[main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 96ms. Found 3 JPA repository interfaces.
[main] INFO org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'repositoryConfig' of type [com.example.app.config.RepositoryConfig$$EnhancerBySpringCGLIB$$4ffca507] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[main] ERROR org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@eafc191] to prepare test instance [com.example.app.test.tests.UserDaoTests@37313c65]
java.lang.NoClassDefFoundError: org.springframework.beans.FatalBeanException

我應該如何正確加載應用程序上下文?

用戶道測試

@ActiveProfiles("dev")
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes= {RepositoryConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
public class UserDaoTests {

private UserRepository userRepository;

@Autowired
private DataSource dataSource;

@Autowired
public void setUserRepository (UserRepository userRepository) {
    this.userRepository = userRepository;
}

private User user1 = new User("user", "userpass", true);

@Before
public void init() {
    System.out.println("Before running tests: init");
    JdbcTemplate jdbc = new JdbcTemplate(dataSource);
    jdbc.execute("delete from sec.authorities");
    jdbc.execute("delete from sec.users");
}

@Test
public void testExists () {
    userRepository.save(user1);
    System.out.println("Users created, test exists");
    assertTrue("User should exist", userRepository.existsByUsername("user"));
    assertFalse("User should not exist", userRepository.existsByUsername("abcdefghj"));
}
}

存儲庫配置

@Configuration
@ComponentScan("com.example.app.dao")
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {
        "com.example.app.dao"
}, entityManagerFactoryRef = "entityManagerFactory",
        transactionManagerRef = "transactionManager")
public class RepositoryConfig {
    
    @Profile("production")
    @Bean(name = "dataSource")
    public DataSource dataSource() {
        JndiDataSourceLookup lookup = new JndiDataSourceLookup();
        return lookup.getDataSource("java:jboss/datasources/postgresqlDS");
    }
    
    @Profile("dev")
    @Bean(name = "dataSource")
    public DataSource jdbcDataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setConnectionProperties(jdbcProperties().toString());
        return dataSource();
    }
    
    
   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean emf 
        = new LocalContainerEntityManagerFactoryBean();
      emf.setDataSource(dataSource());
      emf.setPackagesToScan(new String[] { "com.example.app.dao" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      emf.setJpaVendorAdapter(vendorAdapter);
      emf.setJpaProperties(hibernateProperties());

      return emf;
   }
    
    private final Properties hibernateProperties() {
       //...
    }
    
    private final Properties jdbcProperties() {
        Properties jdbcProperties = new Properties();
        jdbcProperties.setProperty("driverClassName", "${jdbc.driver}");
        jdbcProperties.setProperty("url", "${jdbc.url}");
        jdbcProperties.setProperty("username", "${jdbc.username}");
        jdbcProperties.setProperty("password", "${jdbc.password}");
        return jdbcProperties;
    }
    
    @Bean
    public TransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
        transactionManager.setDataSource(dataSource());
        return transactionManager;
    }
    
    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptiontranslator() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

用戶存儲庫

public interface UserRepository extends CustomizedSave<User>, CrudRepository<User, Long> {

    Optional<User> findByUsername(String username);
    Boolean existsByUsername(String username);
}

定制的SaveImpl

@Repository
public class CustomizedSaveImpl implements CustomizedSave<User>{    
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    
    @PersistenceContext
    EntityManager em;
    
    public CustomizedSaveImpl() {
        System.out.println("successfully loaded users DAO");
    }

    public User save (User user) {
        //...
    }   
}

這是由於創建循環引用的錯字: jdbcDataSource()應該return datasource而不是返回數據源return dataSource();

由於其中一個dataSource bean 指向另一個而引發異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM