[英]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.