What is a test fixture

Tests need to run against the background of a known set of objects. This set of objects is called a test fixture. When you are writing tests you will often find that you spend more time writing the code to set up the fixture than you do in actually testing values.

The purpose of a test fixture is to ensure that there is a well known and fixed environment in which tests are run so that results are repeatable. Some people call this the test context.

Examples of fixtures:

Loading a database with a specific, known set of data
Erasing a hard disk and installing a known clean operating system installation
Copying a specific known set of files
Preparation of input data and set-up/creation of fake or mock objects

One of the most time-consuming parts of writing tests is writing the code to set the world up in a known state and then return it to its original state when the test is complete. This known state is called the fixture of the test.

Importance of flushing data in unit test cases

While writing unit tests it is a good practice to clear and flush the session. When application is executed in real time there are several request and response or different transactions due to which the session/cache gets cleared. However while running unit test, everything happens as the part of single process ie the session (especially hibernate) has rotten values or old references which gives some exceptions at times.

Exception :
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.ptc.fusion.model.learningitem.OnlineCourse#1]
at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:613)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate

Code Example :

learningItemRepository.saveLearningItem(c3);

sessionFactory.getCurrentSession().flush();
sessionFactory.getCurrentSession().clear();

Map<FusionLocale, RootLearningItem> mapBeforeUnMapping = learningItemService.findEquivalentLearningItems(c2);
assert mapBeforeUnMapping.size() == 2;
assert mapBeforeUnMapping.values().contains(c1);
assert mapBeforeUnMapping.values().contains(c2);

sessionFactory.getCurrentSession().flush();
sessionFactory.getCurrentSession().clear();

boolean unMappingSuccessful = learningItemService.unMapEquivalentLearningItem(c1);
assert  unMappingSuccessful;

Hence it is always a good practice to clear/flush session after repository calls or hibernate transactions to make unit test case robust.