Thu, Jan 21, 2021
Read in 5 minutes
Junit is a famous framework for java unit testing. In this article ,we are going to explore the below topics :
In simple term , testing the individual methods using piece of code (code written using junit framework).
While writing unit test case for a method ,check for the below points :
Junit has assertion method for primitive types (int ,double ….etc) and objects and arrays.As per the junit documentation ,the input parameter order for the assertion method is “expected value " followed by the “actual value”.
Start writing the unit test method with @Test:
In the App class we have two methods getProducts() and addProducts().So we can write a test method “productTest” to add the product and get the product list.
App.java
public class App {
List<Product> productList = new ArrayList<Product>();
public List addProdducts(Product p) {
productList.add(p);
return productList;
}
public Product getProduct(String pid) throws InvalidProductIDException {
int i;
if (pid.isEmpty() || !pid.matches("[0-9]+"))
throw new InvalidProductIDException("invalid product" + pid);
for (i = 0; i < productList.size(); i++) {
if (productList.get(i).getPid() == pid) {
break;
}
}
return productList.get(i);
}
}
For this logic ,we can write the below test cases
package com.theprogrammerguide.unittestdemo;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.contains;
//import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class AppTest
{
Product p = new Product();
@Test
public void testProduct() throws InvalidProductIDException {
List<Product> productList = new ArrayList<Product>();
p.setpDescription("desc");
p.setPid("1");
p.setpName("p1");
App app = new App();
productList = app.addProdducts(p);
assertEquals(1, productList.size());
assertEquals(app.getProduct("1"), p);
productList.add(app.getProduct("1"));
// assert an Iterable contains elements with a certain property
assertThat(app.getProduct("1"), hasProperty("pName", equalTo("p1")));
// assertThat(p, hasProperty("pName", equalTo("p1")));
assertThat(productList, contains(hasProperty("pName", is("p1")), hasProperty("pid", is("1"))));
}
// to check the exception
@Test(expected = InvalidProductIDException.class)
public void testExcpetion() throws InvalidProductIDException {
App app = new App();
app.getProduct("");
}
}
You can check the exception using
- @Test(expected = InvalidProductIDException.class)
- @Test(expected = InvalidProductIDException.class)
- public void testExcpetion() throws InvalidProductIDException {
- App app = new App();
- app.getProduct("");
Here the test case will be pass if the exception is thrown.So We are passing null as input to get the exception .
How to assert an Iterable contains elements with a certain property?
To verify the certain property ,you can use hamcrest api.
The below packages are useful from the hamcrest.
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
This “hasProperty " class is useful to check for the certain property of an element .
assertThat(app.getProduct(“1”), hasProperty(“pName”, equalTo(“p1”)));
“The method assertThat(T, Matcher<? super T>) in the type MatcherAssert is not applicable for the arguments” Error:
Sometimes ,When you are not using proper parameters for the assertThat method ,you will get the above error.
For this line
assertThat(productList, contains(hasProperty(“pName”, is(“p1”)), hasProperty(“pid”, is(“1”))));
if you are not passing the “productList” ,you will get the above problem.
And also ,you have to add the dependency for the “hamcrest” package.
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-junit -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-junit</artifactId>
<version>2.0.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
To run ,right click project and select “Run As " and select “Junit Test”. Or select “Maven Test”.
In eclipse ,select “show view " and select junit.By this you can see the junit Run results like below screen
To check the unit test coverage :
Install EclEmma Java code coverage plugin for eclipse and Right click the project ,select “Coverage As” and select “Junit Test”
In unit testing ,there wont be any connection with database or any other external systems. Just you need to mock the dependencies and write testing the single method.
But in integration ,testing you will integrate all the external systems ,databases and you will the software end to end. You will fetch the data from the database and get the data from the webservice.