samedi 28 octobre 2017

How to test dao layer without marking the classes transactional

I'm supposed to write unit tests for DAO layer. I have DAO classes like so:

@Repository
public class CustomerDaoImpl implements CustomerDao {

    @PersistenceContext
    private EntityManager em;

    // some methods ...
}

The application context in ApplicationContext.java is configured like so:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
@ComponentScan(basePackages = "/*censored*/")
public class ApplicationContext {

    @Bean
    public JpaTransactionManager transactionManager() {
        return new JpaTransactionManager(entityManagerFactory().getObject());
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean jpaFactoryBean = new LocalContainerEntityManagerFactoryBean();
        jpaFactoryBean.setDataSource(db());
        jpaFactoryBean.setLoadTimeWeaver(instrumentationLoadTimeWeaver());
        jpaFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        return jpaFactoryBean;
    }

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean() {
        return new LocalValidatorFactoryBean();
    }

    @Bean
    public LoadTimeWeaver instrumentationLoadTimeWeaver() {
        return new InstrumentationLoadTimeWeaver();
    }

    @Bean
    public DataSource db() {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.DERBY).build();
        return db;
    }
}

And the test class like so:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ApplicationContext.class)
public class TestCustomerDao extends AbstractTestNGSpringContextTests 
{

    @Autowired
    private CustomerDao customerDao;

    @Test
    public void someTest() {
        // ... some test
    }
}

How do I run the unit test without having to mark the DAO class using the @Transactional annotation?

I read in other SO posts that @Transactional should be used at the service layer level. However, I'm supposed to write tests for DAO layer, without any service layer.

If I don't mark the DAO classes with the @Transactional annotation, I'm getting the following error: javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call emerging from a method in the DAO class that is calling em.persist(entity).

Sorry if this is a stupid question, but I'm all new to this.

Aucun commentaire:

Enregistrer un commentaire