Teste autônomo usando um banco de dados na memória
1. Visão geral
Neste tutorial, vamoscreate a simple Spring application which relies on an in-memory database for testing.
Para o perfil padrão, o aplicativo terá uma configuração de banco de dados MySQL independente, que exige a instalação e execução do servidor MySQL, com um usuário e banco de dados adequados.
Para tornar o teste do aplicativo mais fácil, abandonaremos a configuração adicional exigida pelo MySQL e, em vez disso, usaremos um banco de dados na memóriaH2 para executar os testes JUnit.
2. Dependências do Maven
Para o desenvolvimento, precisamos das seguintes dependências:
org.springframework
spring-test
4.3.7.RELEASE
org.springframework.data
spring-data-jpa
1.11.1.RELEASE
com.h2database
h2
1.4.194
org.hibernate
hibernate-entitymanager
5.2.9.Final
As versões mais recentes despring-test,spring-data-jpa,h2 ehibernate-entitymanager podem ser baixadas do Maven Central.
3. Modelo de dados e repositório
Vamos criar uma classeStudent simples que será marcada como uma entidade:
@Entity
public class Student {
@Id
private long id;
private String name;
// standard constructor, getters, setters
}
A seguir, vamos criar uma interface de repositório baseada em Spring Data JPA:
public interface StudentRepository extends JpaRepository {
}
Isso permitirá que o Spring crie o suporte para manipulação de objetosStudent.
4. Fontes de propriedade separadas
Para permitir o uso de diferentes configurações de banco de dados no modo padrão e no modo de teste, podemos ler as propriedades do banco de dados de um arquivo cuja localização é diferente, dependendo do modo de execução do aplicativo.
For normal mode, the properties file will reside in src/main/resources, and for the testing method, we will use a properties file in the src/test/resources folder.
Ao executar um teste, o aplicativo procurará primeiro os arquivos na pastasrc/test/resources. Se o arquivo não for encontrado neste local, será utilizado aquele definido na pastasrc/main/resources. Se o arquivo estiver presente no caminhotest, ele substituirá aquele do caminhomain.
4.1. Definindo os Arquivos de Propriedade
Vamos criar um arquivopersistence-student.properties na pastasrc/main/resources que define propriedades para uma fonte de dados MySQL:
dbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/myDb
jdbc.user=tutorialuser
jdbc.pass=tutorialpass
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=create-drop
No caso da configuração acima, precisaremos ter o banco de dadosmyDb criado e o usuáriotutorialuser/tutorialpass configurado.
Como queremos usar um banco de dados na memória para teste, criaremos um arquivo semelhante com o mesmo nome na pastasrc/test/resources, contendo propriedades com as mesmas chaves e valores específicos do banco de dadosH2:
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create
Configuramos o banco de dadosH2 para viver na memória e ser criado automaticamente, depois fechado e descartado quando a JVM for encerrada.
4.2. Configuração JPA
Vamos criar uma classe@Configuration que procura um arquivo chamadopersistence-student.properties como uma fonte de propriedade e cria umDataSource usando as propriedades do banco de dados definidas nele:
@Configuration
@EnableJpaRepositories(basePackages = "org.example.persistence.dao")
@PropertySource("persistence-student.properties")
@EnableTransactionManagement
public class StudentJpaConfig {
@Autowired
private Environment env;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
// configure entityManagerFactory
// configure transactionManager
// configure additional Hibernate Properties
}
5. Criação de um teste JUnit
Vamos escrever um teste JUnit simples com base na configuração descrita acima que usaStudentRepository para salvar e recuperar uma entidadeStudent:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
classes = { StudentJpaConfig.class },
loader = AnnotationConfigContextLoader.class)
@Transactional
public class InMemoryDBTest {
@Resource
private StudentRepository studentRepository;
@Test
public void givenStudent_whenSave_thenGetOk() {
Student student = new Student(1, "john");
studentRepository.save(student);
Student student2 = studentRepository.findOne(1);
assertEquals("john", student2.getName());
}
}
Our test will run in an entirely self-contained manner - criará um banco de dadosH2 na memória, executará instruções, feche a conexão e eliminará o banco de dados, como podemos ver no log:
INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Hibernate: drop table Student if exists
Hibernate: create table Student (id bigint not null, name varchar(255), primary key (id))
Mar 24, 2017 12:41:51 PM org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources
INFO: HHH000476: Executing import script 'org.hiber[email protected]1b8f9e2'
Hibernate: select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from Student student0_ where student0_.id=?
Hibernate: drop table Student if exists
6. Conclusão
Neste exemplo rápido, mostramos como podemos executar um teste independente usando um banco de dados na memória.
Como sempre, o código-fonte completo pode ser encontradoover on GitHub.