It is important to test a happy path, but it is also very important to test and analyze the negative impact by writing the negative test cases. Refer the screen shot :
Tag Archives: JUnit
testNG: How to write time test
Some time performance is critical. Lets a repository call does return the response withing request time out units then it will cause the application to break. Just to keep those things and performance in mind, testNG tests can be calibrate on the measure of time in milli seconds.
The “Time Test” means if an unit test takes longer than the specified number of milliseconds to run, the test will terminated and mark as failed.
import org.testng.annotations.*;public class TestNGTest4 { @Test(timeOut = 1000) public void infinity() { while (true); // userRepository.getAllUsersInEntireWorld(); } }
In above example, the infinity() method will not return, so the TestNG engine will mark it as failed and throw an exception
FAILED: infinity org.testng.internal.thread.ThreadTimeoutException: Method public void TestNGTest4.infinity() didn't finish within the time-out 1000 ... Removed 18 stack frames
testNG : How to ignore or disable a test in testNG
Some times a failing test causes the build to fail. In that cases before the test is fixed a quick remedy is to disable the test to get the build passed. That can be done easily through annotation.
@Test(enabled=false)
The TestNG engine will just bypass this method.
import org.testng.annotations.*; public class TestNGTest3 { @Test(enabled=false) public void divisionWithException() { System.out.println("Method is not ready yet"); } }
In above example, TestNG will not test the divisionWithException() method.
TestNG : Expected Exception Test
It is always good to test the working and output of your unit. But it is more important to test the negative behavior to make application robust. What if you are expecting an exception from a part of code which is not thrown. the point where application has to get terminated, it is moving smoothly to get a dead lock or a pitty crash. Just to save such situation Testing of exception generation is code is very important. There are annotation in TestNG frame work which helps to make is an easy task.
Example
import org.testng.annotations.*; public class TestNGTest2 { @Test(expectedExceptions = ArithmeticException.class) public void divisionWithException() { int i = 1/0; } }
In above example, the divisionWithException() method will throw an ArithmeticException Exception, since this is an expected exception, so the unit test will pass.
More advanced example can be observed in the snap shot attached.
Where the scenarios to test says – “Calling this method with null argument throws Exception”.
The test will go green if exception is thrown, else it will go red.
TestNG : Basic Annotations used in testNG
This blog introduces the basic annotation supported in TestNG.
import java.util.*; import org.testng.Assert; import org.testng.annotations.*; public class TestNGTest1 { private Collection collection; @BeforeClass public void oneTimeSetUp() { // one-time initialization code System.out.println("@BeforeClass - oneTimeSetUp"); } @AfterClass public void oneTimeTearDown() { // one-time cleanup code System.out.println("@AfterClass - oneTimeTearDown"); } @BeforeMethod public void setUp() { collection = new ArrayList(); System.out.println("@BeforeMethod - setUp"); } @AfterMethod public void tearDown() { collection.clear(); System.out.println("@AfterMethod - tearDown"); } @Test public void testEmptyCollection() { Assert.assertEquals(collection.isEmpty(),true); System.out.println("@Test - testEmptyCollection"); } @Test public void testOneItemCollection() { collection.add("itemA"); Assert.assertEquals(collection.size(),1); System.out.println("@Test - testOneItemCollection"); } }
Result
@BeforeClass - oneTimeSetUp @BeforeMethod - setUp @Test - testEmptyCollection @AfterMethod - tearDown @BeforeMethod - setUp @Test - testOneItemCollection @AfterMethod - tearDown @AfterClass - oneTimeTearDown PASSED: testEmptyCollection PASSED: testOneItemCollection
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.