JUnit4 5 Mockito
JUnit4 5 Mockito
and Mockito
Introduction to Junit 4
Lesson Objectives
3
Why is Testing Necessary
4
What is Unit Testing
5
What is Test-Driven Development (TDD)
6
Why Unit Testing
7
What is JUnit
8
Why JUnit
JUnit allows you to write tests faster while increasing quality and
stability.
It is simple, elegant, and inexpensive.
The tests check their own result and provide feedback immediately.
JUnit tests can be put together in a hierarchy of test suites.
The tests are written in Java.
JUnit allows you to write tests faster while increasing quality and
stability.
It is simple, elegant, and inexpensive.
The tests check their own result and provide feedback immediately.
JUnit tests can be put together in a hierarchy of test suites.
The tests are written in Java.
9
Steps for Installing JUnit
10
Using JUnit within Eclipse
11
Using JUnit within Eclipse (Contd.)
import org.junit.Test;
import static org.junit.Assert.*;
public class TestHelloWorld {
@Test
public void testSay() {
HelloWorld hi = new HelloWorld();
assertEquals("Hello World!", hi.say());
}}
class HelloWorld{
String say(){
return “Hello World!”}
}
12
Using JUnit within Eclipse (Contd.)
13
Annotation Types in JUnit4.x
14
Example Using JUnit
•Create a new Java project called junit-app
•Create package, com.sapient.service in src folder, add create the
following class in it.
public class HelloWorld {
private String message; public void setMessage(String
message) {
public HelloWorld() { this.message = message;
this.message="Hello World!!"; }
}
public String myMessage() {
public HelloWorld(String message) { return "Hi!"+this.message;
this.message=message; }
} }
15
Example Using JUnit
•Create a new source folder test (right-click on the project and select
New → Source Folder)
16
Example Using JUnit
In the following window ensure that the New JUnit 4 test flag is selected and
set the source folder to test, so that your test class gets created in this folder.
17
Example Using JUnit
Click on Next button and select the methods that you want to test.
18
HelloWorldTest
@Before
public void beforeMethod() {
System.out.println("Before method");
}
@Test
public void testGetMessage() {
HelloWorld helloWorld=new HelloWorld();
assertEquals("Hello World!!",helloWorld.getMessage());
}
@Test
@Ignore
public void testMyMessage() {
HelloWorld helloWorld=new HelloWorld();
assertEquals("Hello World!!",helloWorld.myMessage());
} Contd…
19
Contd… HelloWorldTest
Right-click on your new test class and select Run-As → JUnit Test.
@After
public void afterMethod() {
System.out.println("After method");
}
@BeforeClass
public static void beforeClass() {
System.out.println("Before all methods");
}
@AfterClass
public static void afterClass() {
System.out.println("After all methods");
}
20
Assert Statements in JUnit
21
Using @Before and @After
22
Using @Before and @After
Example of @Before:
@Before
public void beforeEachTest() {
Calculator cal=new Calculator();
Calculator cal1=new Calculator(“5”, “2”); }
Example of @After:
@After
public void afterEachTest() {
Calculator cal=null;
Calculator cal1=null; }
23
Testing Exceptions
@Test(expected = ArithmeticException.class)
public void divideByZeroTest() {
calobj.divide(15,0);
}
24
Using @BeforeClass and @AfterClass
25
Using @BeforeClass and @AfterClass
Example of @BeforeClass:
@BeforeClass
public static void beforeAllTests() {
Connection conn=DriverManager.getConnection(….);}
Example of @AfterClass:
@AfterClass
public static void afterAllTests() {
conn.close; }
26
Using @Ignore
27
Using @Ignore
@Ignore
public class TestCal {
@Test public void addTest(){ …. }
@Test public void subtractTest(){…..}
}
28
Unit Testing
Start with writing tests for methods having the fewest dependencies
and then work your way up.
Ensure that tests are simple, preferably with no decision making.
Use constant, expected values in the assertions instead of
computed values wherever possible.
Ensure that each unit test is independent of all other tests.
Clearly document all the tests.
Test all methods whether public, protected, or private.
Test the exceptions.
29
JUnit
Do not use the constructor of test case to setup a test case, instead
use an @Before annotated method.
Do not assume the order in which tests within a test case should
run.
Place tests and the source code in the same location.
30
Advanced Testing Concepts
Lesson Objectives
32
Composing Test into Test Suites
33
Composing Test into Test Suites
Example:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith( Suite.class)
@Suite.SuiteClasses({ TestCalAdd.class, TestCalSubtract.class,
TestCalMultiply.class, TestCalDivide.class })
public class CalSuite {
// the class remains completely empty,
// being used only as a holder for the above annotations
}
34
Test Suite Demo
@RunWith(Suite.class)
@Suite.SuiteClasses({ TestPerson1.class,
TestPerson2.class,TestPersonFixture.class})
public class TestPersonSuite {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("Now running the Test Suite");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("The Test Suite is completed");
}
35
Parameterized Test class
Parameterized tests allow you to run the same test with different data.
To specify parameterized tests:
Annotate class with @RunWith(Parameterized.class)
Add a public static method that returns a Collection of data.
• Each element of the collection must be an Array of the various parameters used for the test.
Add a public constructor that uses the parameters.
36
Parameterized Test class
•JUnit allows us to use parameters in a test class.
•This class can contain one test method and this method is executed with the
different parameters provided.
•Mark a test class as a parameterized test with
the @RunWith(Parameterized.class) annotation.
•We should also create a constructor in which we store the values for each
test.
•The number of elements in each array provided by the method annotated
with @Parameters must correspond to the number of parameters in the
constructor of the class.
37
Reusing Tests
Example:
@RunWith(Parameterized.class)
public class SomethingTest {
@Parameters
public static Collection<Object[]> data() { …. }
public SomethingTest()
{…..}
@Test
public void testValue()
{…..}
}
38
Parameterized test class
The following code shows an example for a parameterized test.
We will test the multiply() method of the MyCalculator class
package com.sapient.service;
Contd…
39
Contd…
Parameterized test class
If you run this test class, the test method is executed with each defined parameter.
In the above example the test method is executed five times
@RunWith(Parameterized.class)
public class MyCalculatorParameterized1 {
private double operand1;
@Parameters
public static Collection<Object[]> data(){
return Arrays.asList(new Object[][] {
{25}, {100}, {50}, {10},{5}
});
}
Contd…
40
Parameterized test class
Contd…
@Test
public void testMultiply() {
MyCalculator myCalculator=new MyCalculator();
assertEquals(operand1*operand1,myCalculator.multiply(operand1,operand1),0.1);
}
41
Parameterized test class with 2 parameters
@RunWith(Parameterized.class)
public class MyCalculatorParameterized2 {
private double operand1;
private double operand2;
@Parameters
public static Collection<Object[]> data(){
return Arrays.asList(new Object[][] {
{2,3}, {4,5}, {5,6},
});
} Contd…
42
Parameterized test class with 2 parameters
@Test
public void testMultiply() {
MyCalculator myCalculator=new MyCalculator();
assertEquals(operand1*operand2,myCalculator.multiply(operand1,
operand2),0.1);
}
43
Introduction to Junit 5
Introduction to Junit 5
JUnit Jupiter
This module includes new programming and extension models for writing tests in
JUnit 5. New annotations in comparison to JUnit 4 are:
@DisplayName – defines custom display name for a test class or a test method
@BeforeEach – denotes that the annotated method will be executed before each
test method (previously @Before)
@AfterEach – denotes that the annotated method will be executed after each test
method (previously @After)
@BeforeAll – denotes that the annotated method will be executed before all test
methods in the current class (previously @BeforeClass)
@AfterAll – denotes that the annotated method will be executed after all test
methods in the current class (previously @AfterClass)
@Test
void testCase() {
//Test will pass
Assertions.assertArrayEquals(new int[]{1,2,3}, new int[]{1,2,3}, "Array Equal Test");
assertNotSame() asserts that expected and actual DO NOT refer to the same
object. Similarly, assertSame() method asserts that expected and actual refer
to exactly same object.
@Test
void testCase() {
String originalObject = "Hello World";
String cloneObject = originalObject;
String otherObject = "example.com";
Assumptions are used to run tests only if certain conditions are met.
This is typically used for external conditions that are required for the test to
run properly, but which are not directly related to whatever is being tested.
Ex.
@RunWith(JUnitPlatform.class)
@SelectPackages("com.sapient")
public class AllUnitTest {}
@RunWith(JUnitPlatform.class)
@SelectClasses({AssertionTest.class, AssumptionTest.class,
ExceptionTest.class})
public class AllUnitTest {}
Introduction To Mockito
53
Mockito
Mockito is a mocking framework, JAVA-based library that is used for effective
unit testing of JAVA applications.
What is Mocking?
Mocking is a way to test the functionality of a class in isolation.
Mocking does not require a database connection or properties file read or file
server read to test a functionality.
Mock objects do the mocking of the real service. A mock object returns a dummy
data corresponding to some dummy input passed to it.
What is Mockito?
Mockito facilitates creating mock objects seamlessly. It uses Java Reflection in
order to create mock objects for a given interface.
We do not create real objects, rather ask mockito to create a mock for the
class.
@Mock
HashMap<String, Integer> mockHashMap;
@Test
public void saveTest(){
mockHashMap.put("A", 1);
assertEquals(0, mockHashMap.size());
}
@Spy annotation
@Spy
The @Spy annotation is used to create a real object and spy on that real
object. A spy helps to call all the normal methods of the object while still
tracking every interaction, just as we would with a mock.
@Spy
HashMap<String, Integer> hashMap;
@Test
public void saveTest(){
hashMap.put("A", 10);
assertEquals(1, hashMap.size());
assertEquals(new Integer(10), (Integer) hashMap.get("A"));
}
@Captor annotation
The @Captor annotation is used to create an ArgumentCaptor instance which
is used to capture method argument values for further assertions.
@Captor Example
@Mock
HashMap<String, Integer> hashMap;
@Captor
ArgumentCaptor<String> keyCaptor;
@Captor
ArgumentCaptor<Integer> valueCaptor;
@Test
public void saveTest() {
hashMap.put("A", 10);
assertEquals("A", keyCaptor.getValue());
assertEquals(new Integer(10), valueCaptor.getValue());
}
@Mock and @InjectMocks
@Mock creates a mock whereas @InjectMocks creates an instance of the
class and injects the mocks that are created with the @Mock (or @Spy)
annotations into this instance.
Note that you must use
@RunWith(MockitoJUnitRunner.class) or Mockito.initMocks(this) to initialize these
mocks and inject them.
@RunWith(MockitoJUnitRunner.class)
public class SomeManagerTest {
@InjectMocks
private SomeManager someManager;
@Mock
private SomeDependency someDependency; // this will be injected into someManager
//tests...
}
Thank You!