Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Problema com o teste do ProdutoDAO

Minha classe produtoDAOTest ainda está usando o banco de desenvolvimento, causando erro no teste. O teste só dá certo quando eu mudo a url do banco na classe JPAConfiguration para usar o banco de testes.

package br.com.casadocodigo.loja.dao;

import java.math.BigDecimal;
import java.util.List;

import javax.transaction.Transactional;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import br.com.casadocodigo.loja.buildes.ProdutoBuilder;
import br.com.casadocodigo.loja.configurantion.JPAConfiguration;
import br.com.casadocodigo.loja.configuration.DataSourceConfigurationTest;
import br.com.casadocodigo.loja.model.Produto;
import br.com.casadocodigo.loja.model.TipoPreco;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { JPAConfiguration.class, ProdutoDAO.class, DataSourceConfigurationTest.class })
@ActiveProfiles("test")
public class produtoDAOTest {

    @Autowired
    private ProdutoDAO produtoDao;

    @Transactional
    @Test
    public void deveSomarTodosPrecosPorTipoLivro() {

        List<Produto> LivrosImpresso = ProdutoBuilder.newProduto(TipoPreco.IMPRESSO, BigDecimal.TEN).more(3).buildAll();

        List<Produto> LivrosEbook = ProdutoBuilder.newProduto(TipoPreco.EBOOK, BigDecimal.TEN).more(3).buildAll();

        LivrosImpresso.stream().forEach(produtoDao::gravar);
        LivrosEbook.stream().forEach(produtoDao::gravar);

        // BigDecimal valorImpresso =
        // produtoDao.somaPrecoPorTipo(TipoPreco.IMPRESSO);
        // Assert.assertEquals(new BigDecimal(40).setScale(2), valorImpresso);

        BigDecimal valorEbook = produtoDao.somaPrecoPorTipo(TipoPreco.EBOOK);
        Assert.assertEquals(new BigDecimal(40).setScale(2), valorEbook);

    }

}
package br.com.casadocodigo.loja.configuration;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class DataSourceConfigurationTest {

    @Bean
    @Profile("test")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("");
        dataSource.setUrl("jdbc:mysql://localhost:3306/casadocodigo_test");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }

}
package br.com.casadocodigo.loja.configurantion;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
public class JPAConfiguration {

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();

        factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        factoryBean.setDataSource(dataSource());

        factoryBean.setJpaProperties(aditionalProperties());
        factoryBean.setPackagesToScan("br.com.casadocodigo.loja.model");

        return factoryBean;

    }

    private Properties aditionalProperties() {
        Properties jpaProperties = new Properties();
        jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        jpaProperties.setProperty("hibernate.show_sql", "true");
        jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");
        return jpaProperties;
    }

    @Bean
    @Profile("dev")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("");
        dataSource.setUrl("jdbc:mysql://localhost:3306/casadocodigo");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }

    @Bean
    public JpaTransactionManager jpaTransactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

}
6 respostas

Bom, não vi nada de errado no código.. um erro comum é esquecer de deixar a annotation de profile na classe JPAConfiguration, mas não foi o seu caso. Tem como liberar o código no github?

E ai Alberto, blz? Segue o link:

https://github.com/CarlosEReis/SpringMVCII

E ai Alberto!

Conseguiu dar uma olhada?

Olá Carlos,

Clonei seu projeto aqui e seu teste está rodando normalmente =]

Veja nessa imagem => https://drive.google.com/file/d/0B4DwEgACUW1rSnlGbzJ2clJYT1E/view

A única coisa que alterei foi o nome das bases - como deve ter percebido - pra não coincidir com as bases que já tinha por aqui.

(EDITED) Ops! Não foi um bom teste ... Estou dando uma olhada aqui!

solução!

Opa Carlos,

Agora sim, problema detectado. Vamos a ele!

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource){

    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    JpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();

    factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
    factoryBean.setDataSource(dataSource());

    factoryBean.setJpaProperties(aditionalProperties());
    factoryBean.setPackagesToScan("br.com.casadocodigo.loja.model");

    return factoryBean;
}

No momento em que a JPA cria nosso EntityManager, a factory que o gera recebe ao invés do dataSource do parâmetro - injetado pelo contexto do Spring - , uma chamada ao método local dataSource(), que por sua vez retorna o dataSource padrão pra dev.

Trocando para factoryBean.setDataSource(dataSource); o EntityManager já recebe o DataSource correto.

Abraço!

Boa Rafael!

Entendi perfeitamente, muito obrigado.

Abraço.