Eu fiz um teste diferente do que o passado no vídeo, mas percebi que o Spring não está limpando minha tabela quando executo um teste após o outro. Segue exemplo:
ProdutoDAOTest
package br.com.casadocodigo.loja.daos;
// imports omitidos
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { JPAConfiguration.class, ProdutoDAO.class, DataSourceConfigurationTest.class })
@ActiveProfiles("test")
public class ProdutoDAOTest {
@Autowired
private ProdutoDAO daoProduto;
/**
* Inicializar o banco de dados antes de rodar os testes.
*/
@Before
public void init() {
// 50 reais
List<Produto> livrosImpressos = ProdutoBuilder.newProduto(TipoPreco.IMPRESSO, BigDecimal.TEN).more(4)
.buildAll();
// 100 reais
List<Produto> livrosEbook = ProdutoBuilder.newProduto(TipoPreco.EBOOK, BigDecimal.TEN.add(BigDecimal.TEN))
.more(4).buildAll();
// 150 reais
List<Produto> livrosCombo = ProdutoBuilder
.newProduto(TipoPreco.COMBO, BigDecimal.TEN.add(BigDecimal.TEN.add(BigDecimal.TEN))).more(4).buildAll();
gravaMuitos(livrosCombo);
gravaMuitos(livrosEbook);
gravaMuitos(livrosImpressos);
}
/**
* Percorre uma lista de produtos e salva eles no banco de dados
*
* @param lista
*/
private void gravaMuitos(List<Produto> lista) {
lista.forEach(daoProduto::grava);
}
/**
* Teste que vai fazer o processo de verificação dos valores com a API de
* stream para verificar se o código da consulta no BD esta correto
*/
@Test
public void deveSomarTodosOsPrecosPeloTipoDoLivroEbook() {
// busco todos os produtos do banco de dados
List<Produto> todos = daoProduto.listaTodos();
// pego todos os produtos que tem o tipo de preco EBOOK
// PS: criei o método na classe produto que verifica se possui tal tipo
// de preço em seus precos
List<Produto> ebooks = todos
.stream()
.filter(produto -> produto.temTipo(TipoPreco.EBOOK))
.collect(Collectors.toList());
// faço a soma dos valores dos preços para cada produto, somando o preço
// para ebook
// PS: método getValorParaTipo(TipoPreco.EBOOK) percorre a lista de
// preços e pega o valor do EBOOK
BigDecimal valorEbooksStream = ebooks
.stream()
.map(p -> p.getValorParaTipo(TipoPreco.EBOOK))
.reduce(BigDecimal.ZERO, BigDecimal::add);
// valor da soma na consulta do BD
BigDecimal valorEbooksDAO = daoProduto.somaProdutoPeloTipo(TipoPreco.EBOOK);
Assert.assertEquals(valorEbooksDAO, valorEbooksStream);
}
}
JPAConfiguration
package br.com.casadocodigo.loja.configuration;
// imports omitidos
@EnableTransactionManagement
public class JPAConfiguration {
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setJpaVendorAdapter(getAdapter());
factoryBean.setDataSource(dataSource);
factoryBean.setJpaProperties(aditionalProperties());
factoryBean.setPackagesToScan("br.com.casadocodigo.loja.models");
return factoryBean;
}
private Properties aditionalProperties() {
Properties props = new Properties();
props.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
props.setProperty("hibernate.show_sql", "true");
props.setProperty("hibernate.format_sql", "false");
props.setProperty("hibernate.hbm2ddl.auto", "update");
return props;
}
private JpaVendorAdapter getAdapter() {
return new HibernateJpaVendorAdapter();
}
@Bean
@Profile("dev")
public DriverManagerDataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUsername("root");
ds.setPassword("root");
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/casadocodigo");
return ds;
}
}
e, no pacote de teste:
DataSourceConfigurationTest
package br.com.casadocodigo.loja.configuration;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
@Configuration
public class DataSourceConfigurationTest {
@Bean
@Profile("test")
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUsername("root");
ds.setPassword("root");
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/casadocodigo_test");
return ds;
}
}
De primeira, eu fiz com que o método aditionalProperties fosse um bean, e no profile de test eu fazia com que a propriedade hibernate.hbm2ddl.auto
recebesse o valor de create-drop, mas não achei tão interessante, por criar sempre o banco de dados, atitude desnecessária para esse caso.
Pensei também em criar um método com a annotation @After do JUnit, mas não queria ter que ter esse trabalho sempre que fosse escrever um teste.
Alguma ideia?