Bonjour,

J'utilise actuellement sur mon projet Spring 3.1.1 + Hibernate 3 + JUnit 4.

J'effectue actuellement des tests unitaires sur ma couche metier (et non sur la couche DAO) et je rencontre quelques difficultés liées aux transactions puisque j'ai une exception qui me pète à la gueule en me disant :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [fr.gouv.travail.gestionAccords.server.business.gestionDossiers.detailsDossier.coordonees.implementations.AdresseBusinessImpl] is defined: expected single bean but found 0: 
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:271)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1101)
	at fr.gouv.travail.gestionAccords.server.business.gestionDossiers.detailsDossier.AdresseBusinessUnitTest.save(AdresseBusinessUnitTest.java:36)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Le problème ne vient pas de mon bean puisque mon projet tourne mais du test unitaire que je n'arrive pas à faire fonctionner correctement.

Voici le bean en question :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Named("adresseBusinessBean")
public class AdresseBusinessImpl implements IAdresseBusiness
{
	@Inject
	private IAdresseDAO adresseDao;
 
	@Inject 
	private DozerBeanMapper mapper;
 
	@Override
	public List<AdresseDTO> findAll() 
	{
		return ServerTools.convert(mapper, adresseDao.findAll(), AdresseDTO.class);
	}
 
	@Override
	public List<AdresseDTO> findById(List<AdresseBean> adresseBeanList) 
	{
		return ServerTools.convert(mapper, adresseDao.findById(adresseBeanList), AdresseDTO.class);
	}
 
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void save(AdresseBean adresseBean) 
	{
		//.. Du code metier...
 
		adresseDao.save(adresseBean);
 
		// Du code metier...
	}
...
}
Le bean DAO :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Named("adresseDao")
public class AdresseDAOImpl extends HibernateDaoSupport implements IAdresseDAO
{	
	@Inject
	public AdresseDAOImpl(SessionFactory sessionFactory)
	{
		super.setSessionFactory(sessionFactory);
	}
 
	@SuppressWarnings("unchecked")
	public List<AdresseBean> findAll()
	{
		List<AdresseBean> beanList = getHibernateTemplate().find("from AdresseBean");
 
		if(logger.isDebugEnabled())
		{
			logger.debug("Result(s) found : ");
			for(AdresseBean bean : beanList)
			{
				logger.debug(bean.toString());
			}
		}
		return beanList;
	}
 
	@Transactional(propagation=Propagation.MANDATORY)
	public void save(AdresseBean adresseBean)
	{
		getHibernateTemplate().save(adresseBean);
	}
...
Et enfin, mon test unitaire sous JUnit 4 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/applicationContext.xml"})
@TransactionConfiguration(defaultRollback=true)
public class AdresseBusinessUnitTest extends AbstractTransactionalJUnit4SpringContextTests 
{
 
@Test
	public void save() 
	{
		IAdresseBusiness adresseBusiness = (IAdresseBusiness)applicationContext.getBean(AdresseBusinessImpl.class);
 
		/** Initialise un bean avec différentes valeurs **/
		AdresseBean adrBean = (AdresseBean)applicationContext.getBean(AdresseBean.class);
		adrBean.setCodeCommune("75016");
		adrBean.setCodePostal("75016");
		adrBean.setComplementVoie("Complément de la voie");
		adrBean.setLibelleVoie("Libellé de la voie");
		adrBean.setNumeroVoie(29);
		adrBean.setRepetitionVoie("BIS");
		adrBean.setTypeVoie("All");
 
		String ville = "Paris";
		adrBean.setVille(ville);
 
		/** Sauvegarde du bean précédent **/
		adresseBusiness.save(adrBean);
 
		/** Vérifie que le bean a bien été stocké en base **/
		List<AdresseDTO> dtoList = adresseBusiness.findByVille(adrBean);
		Assert.notNull(dtoList);
		Assert.notEmpty(dtoList);
		Assert.isTrue(dtoList.get(0).getVille().equals(ville), "Attention, valeur attendue = '"+ville+"', obtenu :'"+dtoList.get(0).getVille()+"'!");
	}
Vous aurez remarqué que j'ai mis une propagation à REQUIRED dans ma couche BUSINESS et une propagation à MANDATORY dans mon DAO.
Mon transaction manager s'appelle "transactionManager", donc je n'ai pas vu la nécessité d'ajouter l'attribut portant le même nom.

Cela tourne très bien dans mon projet, mais JUnit n'a pas l'air d'aimer d'autant plus que si je supprime le :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
@Transactional(propagation=Propagation.REQUIRED)
de ma couche BUSINESS, alors ça fonctionne !
C'est à ne rien comprendre...

Alors auriez-vous, SVP, une idée ?

Merci d'avance pour vos retours et désolé pour la longueur de mon post !

PS : Je suis débutant en Spring + Hibernate + JUnit.