27105

Why won't the transaction start in my junit test cases?

Question:

I have a Spring 3.1 MVC + Hibernate 3.6 project with its junit4 test suit. My problem is that there is no transaction starting in my test cases, even thought I added a <em>@Transactional</em>.

My test case calls a controller and a dao. In the controller, a transaction is started anyway, so it does not complain. In the dao, I added a <em>@Transactional(propagation = Propagation.MANDATORY)</em> to be sure it will take the test's transaction. And currently it raises an <em>IllegalTransactionStateException</em>, which I guess it means there is no current transaction.

I tried to create programmaticaly an transaction and it does work, which means the AOP proxy to get the dao service is not the cause of the problem. However I want to create a transaction with the <em>@Transactional</em> annotation.

here's my dao:

// ...imports... @Repository("taskDao") @Transactional(propagation = Propagation.MANDATORY) public class TaskHome implements TaskDao { private static final Log log = LogFactory.getLog(TaskHome.class); private SessionFactory sessionFactory; @Autowired public TaskHome(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Task findById(int id) { log.debug("getting Task instance with id: " + id); try { Task instance = (Task) this.sessionFactory.getCurrentSession().get( Task.class, id); // exception raised here! if (instance == null) { log.debug("get successful, no instance found"); } else { log.debug("get successful, instance found"); } return instance; } catch (RuntimeException re) { log.error("get failed", re); throw re; } } ... }

Here's my test case:

// ...imports... @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "/test-config.xml", "/applicationContext.xml" }) @TransactionConfiguration(defaultRollback = true) @Transactional public class TestTaskController { private static ClassPathXmlApplicationContext context; private static TaskDao taskDao; @BeforeClass public static void initHibernate() throws Exception { context = new ClassPathXmlApplicationContext("applicationContext.xml"); taskDao = context.getBean("taskDao", TaskDao.class); } @Test public void testOnSubmit() { // expects an existing default transaction here Task task = taskDao.findById(1); // fails already here // ... calls the controller and does some tests. } }

I searched in all Spring's documentation and googled it in any way I could imagine, but I don't see why the transaction is not started. Any help is very welcome.

Answer1:

When using @RunWith(SpringJUnit4ClassRunner.class) you should obtain beans from the application context created by SpringJUnit4ClassRunner rather than from your own one.

In your case things go wrong because @Transactional on the unit test creates a transaction in the application context managed by SpringJUnit4ClassRunner, but you call methods on the beans obtained from the application context created manually.

So, remove your @BeforeClass method and obtain TaskDao via autowiring:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "/test-config.xml", "/applicationContext.xml" }) @TransactionConfiguration(defaultRollback = true) @Transactional public class TestTaskController { @Autowired private TaskDao taskDao; ... }

<strong>See also:</strong>

<ul><li><a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/testing.html#testcontext-framework" rel="nofollow">9.3.5 Spring TestContext Framework</a></li> </ul>

Recommend

  • How change format time from jSpinner?
  • Not able to read updated data in sqlite database
  • how to avoid the dependencies hell with unit test in angular 2+
  • Perl function name clash
  • CSV and MS-DOS CSV Formats
  • Is it possible to run an application built on sql server 2008 to run with 2005
  • Using constants or global variables in 3 tier console application
  • not able to create VC++ project, with VS11
  • Python Paramiko send CTRL+C to an ssh shell
  • JSF NumberFormatException with f:setPropertyActionListener
  • string.IsNullOrEmpty() Doesn't Seem to Work on a String within a Class within a Class
  • Using extern @class in order to add a category?
  • How to resolve dependencies from one gradle project to another gradle project in my Eclipse workspac
  • How to open multiple instances of a program in Linux
  • Insertion large number of Entities into SQL Server 2012 [duplicate]
  • EF 4.1 DBContext AutoDetectChangesEnabled
  • to implement a spinner in angular2+
  • C function strchr - How to calculate the position of the character?
  • ImportError: cannot import name Pubnub
  • Where can I find tomesh.c?
  • Regarding starting the threads on a condition
  • how do i write assembly code from c#?
  • Memory error in python- how to use more memory
  • Differences in dis-assembled C code of GCC and Borland?
  • How to add git credentials to the build so it would be able to be used within a shell code?
  • Algorithm for a smudge tool?
  • How to access EntityManager inside Entity class in EJB3
  • Opengl-es onTouchEvents problem or a draw problem? [closed]
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Cannot Parse HTML Data Using Android / JSOUP
  • Comma separated Values
  • JTable with a ScrollPane misbehaving
  • Java static initializers and reflection
  • unknown Exception android
  • Checking variable from a different class in C#
  • Observable and ngFor in Angular 2
  • failed to connect to specific WiFi in android programmatically
  • Unable to use reactive element in my shiny app
  • How can I use threading to 'tick' a timer to be accessed by other threads?
  • How to load view controller without button in storyboard?