Closed nyddogghr closed 9 years ago
Hi nyddogghr,
The issue that you described is very interesting. I created a sample application that shows this problem: https://github.com/ekravchenko/testingzone/tree/master/spring-dbunit-issue75
In the sample application I'm using same entity and dataset files that you provided in the example. Instead of DAO I'm using spring-data-jpa CrudRepository but that shouldn't matter cause I could reproduce the issue you described.
If I understand you right testInsert
and testDelete
work but testUpdate
fails. The root of the problem is the @Transactional annotation which causes the tests to be wrapped in the transaction. DBUnit checks the expected dataset however data is not inserted/updated cause it only happens at the end of transaction. If this statement is correct then none of your tests should work.
The reasonable questions is 'why testInsert and testDelete work then'? They work because you have the following line in tests:
assertEquals(nb-1, tempUuidDaoI.getAll().size());
If you don't configure FlushMode then the default value of AUTO will be used. So when you fire tempUuidDaoI.getAll()
at the end of the test it makes hibernate flush before transaction ends, thus making changes visible for DBUnit checks.
Re-write testUpdateUuid in the following way and you will be surprised to find it working:
@Test
@ExpectedDatabase(value = "testUpdate.xml", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void testUpdateUuid() throws Exception {
TempUuid tu = tempUuidDaoI.get(1);
tu.setUuid("4b2f02ca-d857-4c95-b7fa-ee6283ce0d66");
tempUuidDaoI.update(tu);
tu = tempUuidDaoI.get(1);
assertEquals("4b2f02ca-d857-4c95-b7fa-ee6283ce0d66", tu.getUuid());
tempUuidDaoI.getAll();
}
The last line will force the flush.
As a workaround I would suggest flushing manually at the end of the test. session.flush()
or entityManager.flush()
. I wouldn't rely on AUTO flush cause that's not intuitive.
However it would be awesome if this problem could be fixed on the tesing framework level so that users wouldn't have to worry about it.
Hi,
Thank you for your anwser. I have retried this, with your correction, but I'm not able to fix this. I even tried flushing manually :
@Test
@ExpectedDatabase(value = "testUpdate.xml", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void testUpdateUuid() throws Exception {
TempUuid tu = tempUuidDaoI.get(1);
tu.setUuid("4b2f02ca-d857-4c95-b7fa-ee6283ce0d66");
tempUuidDaoI.update(tu);
tu = tempUuidDaoI.get(1);
assertEquals("4b2f02ca-d857-4c95-b7fa-ee6283ce0d66", tu.getUuid());
tempUuidDaoI.getAll();
tempUuidDaoI.flush();
}
But I still have the same error. What tempUuidDaoI.flush() does is simply getSession.flush(). So it should have fixed it. I remember I had also tried this with no result.
So far, I have no anwser, I had to use another way to do what I wanted to do (use jdbc template to avoid the @Transactionnal annotation).
Thanks again even if I can't confirm this is fixed
HI nyddogghr,
Could you please send a link to your sample application in Git? That would really help in sorting this issue out.
Thanks, YK
Hi,
Sorry but for some reason I'm not able to create a sample application for this. I've tried your sample that indeed works, but I have used another way to get past this.
Once again, thank you for your help. I'm closing this since it seems it comes from my project only.
I have the same trouble :( Without flush it does not work
Hi, with the help of flush I was able to make an integration test work on service-level, e.g., see: service integration test
However, it does not work on Mvc-level, when testing the controller, e.g., see: controller integration test
Do you have any idea what is the issue with the MockMvc? Can you advice?
Thanks in advance!
When using @Transactional, TransactionDbUnitTestExecutionListener.class and @ExpectedDatabase, updating a row makes the expected database to always fail.
Here is a exemple :
}
In this code, only the update doesn't work.
The original db :
testDelete.xml :
testUpdate.xml :
testInsert.xml :
I've checked that the methods to update/delete/insert work, as does the dao. I use postgresql for anything else than unit testing for the project. I use hibernate H2 for testing.
Any idea on where does this come from ?