TestNG is an open source automated testing framework which is meant to perform unit, functional, end-to-end, integration testing. TestNG need minimum Java JDK 5. Based on the website,
TestNG is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use like Annotation, Support for parameters etc.
In TestNG, NG means Next Generation. TestNG is similar to JUnit although, it is not a JUnit extension. It is surely motivated from JUnit. Integration testing can be done much better in TestNG in comparison to JUnit.
JUnit vs TestNG
TestNG and JUnit differ at their core behavior:
- JUnit instantiates the class during all of its test methods. This means that these fields are unique or local to each test case we write and they are not shared across test cases, which can be a downside too.
- In TestNG, just one object is created whose state of fields are shared across @Test cases we write.
To enable the use of Mockito annotations in your Test cases like @Mock or @Spy or many other annotations, we must programmatically enable them. This can be done by doing the following:
1 2 3 4 5 6 |
@BeforeMethod public void init() { MockitoAnnotations.initMocks(this); } |
For JUnit, it works out of the box because 2nd @Test
has its own fields and its own mocks.
Mockito with TestNG
Now, let us look at how stubbing in TestNG works, we’ll use Mockito to mock as well.
Prerequisites
I am assuming that you have installed TestNG plugin in eclipse.
Steps for creating Mockito TestNG example.
Step 1:Â Create a simple java maven project.
Maven Dependency
Step 2: Add required dependencies to pom.xml
A Maven dependency is the fastest way to get started with Mockito:
1 2 3 4 5 6 7 8 |
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <dependency> Â Â Â <groupId>org.mockito</groupId> Â Â Â <artifactId>mockito-all</artifactId> Â Â Â <version>1.9.5</version> </dependency> |
Just a single dependency which doesn’t bring any other libraries with it. See here for latest versions of the library.
As we will also be using some TestNG functionality, we will also need its dependency. Let’s add it next,
1 2 3 4 5 6 7 8 9 |
<!-- https://mvnrepository.com/artifact/org.testng/testng --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.11</version> <scope>test</scope> </dependency> |
Your pom.xml will look as below:
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.arpit.java2blog</groupId> <artifactId>MockitoTestNGExample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.testng/testng --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.11</version> <scope>test</scope> </dependency> </dependencies> </project> |
Step 3: Let’s define our class to test:
1 2 3 4 5 6 7 8 9 |
package org.arpit.java2blog.mockito; public class CreateNumber { public int getThreeDigitNumber() { return (int) (Math.random() * 1000); } } |
Finally, let’s put above simple class to test.
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 |
package org.arpit.java2blog.mockito; import org.mockito.Mockito; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestNgTest { private CreateNumber createNumber = null; @BeforeClass public void init() { createNumber = Mockito.mock(CreateNumber.class); } @Test public void testWith_TestNG() { int expected = 100; Mockito.when(createNumber.getThreeDigitNumber()).thenReturn(expected); int actual = createNumber.getThreeDigitNumber(); Assert.assertEquals(actual, expected); } } |
Step 4: Create testing.xml
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="UTF-8"?> <suite name="Number test Suite"> <test name="Create Number test"> <classes> <class name="org.arpit.java2blog.mockito.TestNgTest" /> </classes> </test> </suite> |
Step 5: Run the test
Right click on testng.xml and select "TestNG Suite" and you will get below output:
Be aware that TestNG does not recreate your test class for multiple test methods in the same test class (and, unfortunately, Mockito won’t recreate the @InjecktMocks
objects if the instances are not null), which will lead to your mocks / tested objects not being recreated for different test methods, even though the initMocks
call is in a @beforemethod-annotated method.
Why use TestNG?
Without @Mock
annotation in Mockito, the verify() calls will be made for all @test annotated methods. This issue needs to be fixed, whose only solution is to use this gist or new up the mock in the @Beforemethod
(which didn’t seem reasonable). This default behavior is better, where the mock isn’t expected to persist state from previous tests.