Как поднять тестовую БД в Spring (при тестировании)
Пишу тесты для своего приложения. Использую тестовую БД.
Столкнулся с проблемой:
Error creating bean with name 'jpaDepartmentDaoImpl': Injection of persistence dependencies failed;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'javax.persistence.EntityManagerFactory' available:
expected single matching bean but found 2: testLocalContainerEntityManagerFactoryBean,localContainerEntityManagerFactoryBean
Я понимаю, что Spring ругается на то, что не может понять какой бин подставить, но как мне ему указать, что при тестах использовать мою тестовую конфигурацию, а при обычном использовании - обычную?
DispatcherServletInitTest
package com.aimprosoft.hopak.util.config.dispatcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
@TestOnly
@Configuration
@ComponentScan("com.aimprosoft.hopak")
public class DispatcherServletInitTest implements WebApplicationInitializer {
@Override
public void onStartup(@NotNull ServletContext servletContext) {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.scan("com.aimprosoft.hopak");
ctx.setServletContext(servletContext);
servletContext.addListener(new ContextLoaderListener(ctx));
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
registerHiddenFieldFilter(servletContext);
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter",
new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*");
}
}
JpaConfigTest package com.aimprosoft.hopak.util.config;
import org.jetbrains.annotations.TestOnly;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import java.util.Properties;
@TestOnly
@Configuration
@TestPropertySource("classpath:testDataBase.properties")
@EnableTransactionManagement
@ComponentScan("com.aimprosoft.hopak")
public class JpaConfigTest {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.database-platform}")
private String databasePlatform;
private final Properties prop = new Properties();
{
prop.setProperty("hibernate.show_sql", "true");
prop.setProperty("hibernate.format_sql", "true");
}
@Bean
public DriverManagerDataSource testDriverManagerDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean testLocalContainerEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean localContainer = new LocalContainerEntityManagerFactoryBean();
localContainer.setDataSource(testDriverManagerDataSource());
localContainer.setPackagesToScan("com.aimprosoft.hopak");
localContainer.setJpaVendorAdapter(testHibernateJpaVendorAdapter());
localContainer.setJpaProperties(prop);
return localContainer;
}
@Bean
public HibernateJpaVendorAdapter testHibernateJpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setDatabasePlatform(databasePlatform);
return hibernateJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager testTransactionManager(@Qualifier("testLocalContainerEntityManagerFactoryBean") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
WebApplicationContextConfigTest
package com.aimprosoft.hopak.util.config;
import net.sf.oval.Validator;
import net.sf.oval.configuration.annotation.AnnotationsConfigurer;
import net.sf.oval.guard.GuardInterceptor;
import net.sf.oval.integration.spring.SpringCheckInitializationListener;
import net.sf.oval.integration.spring.SpringValidator;
import org.jetbrains.annotations.TestOnly;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@TestOnly
@Configuration
@EnableWebMvc
@ComponentScan("com.aimprosoft.hopak")
public class WebApplicationContextConfigTest implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver templateResolver() {
InternalResourceViewResolver templateResolver = new InternalResourceViewResolver();
templateResolver.setPrefix("/view");
templateResolver.setSuffix(".jsp");
return templateResolver;
}
@Bean
public SpringValidator validator() {
AnnotationsConfigurer springConfig = new AnnotationsConfigurer();
springConfig.addCheckInitializationListener(SpringCheckInitializationListener.INSTANCE);
Validator validator = new Validator(springConfig);
return new SpringValidator(validator);
}
@Bean
public GuardInterceptor guardInterceptor() {
return new GuardInterceptor();
}
}
Ответы (1 шт):
Я недооценил возможности спринга. И 90% он делает самостоятельно.
Всё, что нам нужно, это создать ещё dataBase.properties (с одинаковыми названиями, как на скрине) и когда вы запустите тесты, спринг сам всё подтянет.
ВАЖНО: ПАПКИ ДОЛЖНЫ БЫТЬ ПОМЕЧЕНЫ,КАК RESOURCES/TEST RESOURCES!!!!!
Для этого в IntelliJIdea
И так! Теперь, всё, что нам нужно:



