Core Java

Java Unit Testing Tutorial

Photo of Mary ZhengMary ZhengMarch 17th, 2020Last Updated: May 25th, 2021
0 2,729 12 minutes read

This is a tutorial for Java unit testing. In this tutorial, I will create a spring boot application which includes test cases written with Junit, Mockito, and Spring test. The overall unit tests cover 90 percent of the application.

You can also check this tutorial in the following video:

Unit Testing Tutorial – video

1. Introduction

This is a tutorial for Java unit testing. A unit is an individual part which can also become a component of a larger system. In Java world, a unit can be a method or a class. Unit testing is a level of software testing where methods and classes are tested so that every unit of the software works as designed.

Unit testing is the foundation of the “Testing Pyramid” outlined byMike Cohn. It should be automated and run whenever there is a code change. With that, development is faster with the following benefits:

  • Codes are more reliable when it has a good amount of code coverage.
  • Codes are more reusable because it’s easy to reuse modular code.
  • The cost of fixing a defect detected during unit testing is lesser comparing to when defects detected at higher levels.
  • It increases confidence when changing code. Every change is tested so the unintended impact of changes is identified.

2. Unit Testing Frameworks

There are lots of Java unit testing frameworks. In this example, I will demonstrate unit testing with the following frameworks:

  • Junit – A standard for Java unit testing which provides@Test annotation to specify tests and assertion methods:assertEquals(),assertTrue(), andassertFalse().
  • Mockito – a mocking framework which provides@Mock annotation to mock the dependency with mocking methods:when,thenReturn,doNothing, anddoThrow.
  • Spring Test and Spring Boot Test – a test library which tests spring boot application.

I will create a spring boot application which contains test classes to test key methods.

Java Unit Testing Tutorial - Class Digram
Figure 1 Class Digram

3. Technologies Used

The example code in this article was built and run using:

  • Java 8
  • Maven 3.3.9
  • Eclipse Oxygen
  • H2
  • Spring boot (which includes Spring test, JUnit, and Mockito)

4. Maven Project

4.1 Dependencies

Pom.xml includes dependencies for this project.

pom.xml

<?xml version="1.0" encoding="UTF-8"?><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>jcg.zheng.demo</groupId><artifactId>junit-demo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>spring-boot-jersey-demo</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.14.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

4.2 Application Properties

In this step, I will create anapplication.properties to configure a H2 database and spring JPA hibernate configuration.

application.properties

spring.datasource.url=jdbc:h2:file:~/main-source;AUTO_SERVER=TRUEspring.datasource.username=saspring.datasource.password=spring.datasource.driver-class-name=org.h2.Driverspring.jpa.hibernate.ddl-auto=createspring.jpa.generate-ddl=truespring.jpa.show-sql=true

4.3 Application

In this step, I will create anApplication.java class which annotates with@SpringBootApplication. It only has a main method to start the application.

Application.java

package jcg.zheng.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

4.4 Person Entity

In this step, I will create aPerson class which represents anentity class. It annotates with@javax.persistence.Entity,@javax.persistence.Id,@javax.persistence.GeneratedValue, etc.

Person.java

package jcg.zheng.demo.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;@Entitypublic class Person {private String companyName;private String fName;private String lName;private String mName;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int personId;public String getCompanyName() {return companyName;}public String getfName() {return fName;}public String getlName() {return lName;}public String getmName() {return mName;}public int getPersonId() {return personId;}public void setCompanyName(String companyName) {this.companyName = companyName;}public void setfName(String fName) {this.fName = fName;}public void setlName(String lName) {this.lName = lName;}public void setmName(String mName) {this.mName = mName;}public void setPersonId(int personId) {this.personId = personId;}}

4.5 User Not Found Exception

In this step, I will create aUserNotFoundException which extends fromRuntimeException.

UserNotFoundException.java

package jcg.zheng.demo.exception;public class UserNotFoundException extends RuntimeException {private static final long serialVersionUID = 3873418545077760440L;private final Integer userId;public UserNotFoundException(String message, Integer userId) {super(message);this.userId = userId;}public Integer getUserId() {return userId;}}

4.6 Person Repository

In this step, I will create aPersonRepository interface which extends fromJpaRepository and have one customized query –findByCompany.

PersonRepository.java

package jcg.zheng.demo.repository;import java.util.List;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.Query;import org.springframework.data.repository.query.Param;import org.springframework.stereotype.Repository;import jcg.zheng.demo.entity.Person;@Repositorypublic interface PersonRepository extends JpaRepository<Person, Integer> {@Query("SELECT person from Person person WHERE person.companyName = :companyName")List<Person> findByCompany(@Param("companyName") String companyName);}

4.7 User

In this step, I will create aUser domain class which has several data members and overwrites theequals andhashCode methods.

User.java

package jcg.zheng.demo.service;public class User {private String companyName;private String firstName;private String lastName;private Integer userId;@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;User other = (User) obj;if (userId == null) {if (other.userId != null)return false;} else if (!userId.equals(other.userId))return false;return true;}public String getCompanyName() {return companyName;}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}public Integer getUserId() {return userId;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((userId == null) ? 0 : userId.hashCode());return result;}public void setCompanyName(String companyName) {this.companyName = companyName;}public void setFirstName(String firstName) {this.firstName = firstName;}public void setLastName(String lastName) {this.lastName = lastName;}public void setUserId(Integer userId) {this.userId = userId;}}

4.8 UserService

In this step, I will create aUserService interface which has four public methods.

UserService.java

package jcg.zheng.demo.service;import java.util.List;public interface UserService {void deleteById(Integer personId);User findById(Integer personId);User save(User user);List searchByCompanyName(String companyName);}

4.9 TransformService

In this step, I will create a spring managed component –TransformService which transforms thePerson entity toUser domain and vice versa.

UserServiceImpl.java

package jcg.zheng.demo.service;import org.springframework.stereotype.Component;import jcg.zheng.demo.entity.Person;@Componentpublic class TransformService {public User toUserDomain(final Person person) {User user = new User();user.setCompanyName(person.getCompanyName());user.setFirstName(person.getfName());user.setLastName(person.getlName());user.setUserId(person.getPersonId());return user;}public Person toUserEntity(final User user) {Person person = new Person();person.setCompanyName(user.getCompanyName());person.setfName(user.getFirstName());person.setlName(user.getLastName());if (user.getUserId() != null) {person.setPersonId(user.getUserId());}return person;}}

4.10 UserServiceImpl

In this step, I will create a spring managed component –UserServiceImpl which implements theUserService interface. It depends on thePersonRepository andTransformServie.

UserServiceImpl.java

package jcg.zheng.demo.service;import java.util.ArrayList;import java.util.List;import javax.transaction.Transactional;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import jcg.zheng.demo.entity.Person;import jcg.zheng.demo.exception.UserNotFoundException;import jcg.zheng.demo.repository.PersonRepository;@Component@Transactionalpublic class UserServiceImpl implements UserService {@Autowiredprivate PersonRepository personDao;@Autowiredprivate TransformService transformer;@Overridepublic void deleteById(Integer personId) {personDao.delete(personId);}@Overridepublic User findById(Integer personId) {Person found = personDao.findOne(personId);if (found == null) {throw new UserNotFoundException("not found user", personId);}return transformer.toUserDomain(found);}@Overridepublic User save(User user) {Person saved = personDao.save(transformer.toUserEntity(user));return transformer.toUserDomain(saved);}@Overridepublic List<User> searchByCompanyName(String companyName) {List<Person> persons = personDao.findByCompany(companyName);List<User> users = new ArrayList<>();for (Person person : persons) {users.add(transformer.toUserDomain(person));}return users;}}

5. JUnit Test

In this section, I will create several test classes that utilize Junit, Mockito, and spring test frameworks. In this example, I will use the following annotations throughout the project.

FrameworkCommon AnnotationsComments
JUnit@TestMark it at a public void method to indicate it is a test case
JUnit@RuleMark it at a public variable to let JUnit run it as a test rule
JUnit@BeforeMark it at a public void method to let Junit execute it before any test case
JUnit@RunWithSpecify a test class with a non-default runner
Spring Test@SpringBootTestSet up application context for the testing purpose
Spring Test@DataJpaTestSet up context to test JpaRepository
Mockito@MockCreate a mock object
Mockito@InjectMocksCreate an object and inject the marked dependencies

Each test case is structured withGiven, When, Then sequences. It sets up the data, invokes the testing method, and verifies the output. This project has 90% code coverage with unit tests.

Figure 2 Code Coverage

5.1 PersonTest

Person is an entity class which annotates with@Entity annotation. It must have a default constructor, so I will test its default constructor in thePersonTest.java

PersonTest.java

package jcg.zheng.demo.entity;import static org.junit.Assert.assertEquals;import org.junit.Test;public class PersonTest {@Testpublic void test_person_default_constructor() {Person testClass = new Person();testClass.setmName("Shan");assertEquals("Shan", testClass.getmName());testClass.setfName("Mary");assertEquals("Mary", testClass.getfName());testClass.setlName("Zheng");assertEquals("Zheng", testClass.getlName());}}

Execute it with maven commandmvn test -Dtest=PersonTest and capture the output here.

Output

Running jcg.zheng.demo.entity.PersonTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 sec - in jcg.zheng.demo.entity.PersonTestResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

5.2 PersonRepositoryTest

In this step, I will use the@DataJpaTest provided by spring test framework to auto-wire theTestEntityManager andPersonRepository from the spring context. It has aTimeout rule to ensure every test must complete within 2 seconds. It has onesetup and four test cases:

  • setup – it verifies that the spring test framework provides the needed beans –entityManger andpersonDao and uses them to create two persons in database for other tests to use.
  • findByCompany_return_emptylist_when_not_found – it returns an empty list when there is no person matching the given company.
  • findByCompany_return_person_when_found – it finds a list of people which matches the given company.
  • findOne_return_null_when_not_found – it returns a null object when it doesn’t find a user based on the person id.
  • findAll_return_list_when_found – it returns all persons in the database as a list.

PersonRepositoryTest.java

package jcg.zheng.demo.repository;import static org.junit.Assert.assertEquals;import static org.junit.Assert.assertNotNull;import static org.junit.Assert.assertNull;import static org.junit.Assert.assertTrue;import java.util.List;import org.junit.Before;import org.junit.Rule;import org.junit.Test;import org.junit.rules.Timeout;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;import org.springframework.test.context.junit4.SpringRunner;import jcg.zheng.demo.entity.Person;@RunWith(SpringRunner.class)@DataJpaTestpublic class PersonRepositoryTest {@Rulepublic Timeout appTimeout = Timeout.millis(2000);@Autowiredprivate TestEntityManager entityManager;@Autowiredprivate PersonRepository personDao;@Beforepublic void setup() {assertNotNull(entityManager);assertNotNull(personDao);// prepare two personsPerson mary = new Person();mary.setfName("Mary");mary.setCompanyName("Test");entityManager.persist(mary);Person alex = new Person();alex.setfName("Alex");alex.setCompanyName("Alex company");entityManager.persist(alex);}@Testpublic void findAll_return_list_when_found() {List<Person> found = personDao.findAll();assertNotNull(found);assertEquals(2, found.size());}@Testpublic void findByCompany_return_person_when_found() {List<Person> found = personDao.findByCompany("Test");assertNotNull(found);assertEquals("Mary", found.get(0).getfName());}@Testpublic void findByCompany_return_emptylist_when_not_found() {List<Person> found = personDao.findByCompany("Test-notExist");assertNotNull(found);assertTrue(found.isEmpty());}@Testpublic void findOne_return_null_when_not_found() {Person found = personDao.findOne(-9);assertNull(found);}}

Execute it with maven commandmvn test -Dtest=PersonRepositoryTest and capture the output here.

Output

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.913 sec - in jcg.zheng.demo.repository.PersonRepositoryTest2020-03-14 16:11:17.596  INFO 140944 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1ed6388a: startup date [Sat Mar 14 16:11:08 CDT 2020]; root of context hierarchy2020-03-14 16:11:17.603  INFO 140944 --- [       Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'Results :Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

5.3 TransformServiceTest

AlthoughTransformService is managed by spring, but it has no dependency to other services. We will test it with two simple Junit test methods:

  • test_toDomain – it tests thetoUserDomain method
  • test_toEntity – it tests thetoUserEntity method

TransformServiceTest.java

package jcg.zheng.demo.service;import static org.junit.Assert.assertEquals;import static org.junit.Assert.assertNotNull;import org.junit.Test;import jcg.zheng.demo.entity.Person;public class TransformServiceTest {private TransformService testClass = new TransformService() ;@Testpublic void test_toDomain() {Person person = new Person();person.setCompanyName("test company");person.setfName("Mary");person.setlName("Zheng");person.setmName("shan");person.setPersonId(1);User user = testClass.toUserDomain(person);assertNotNull(user);assertEquals("test company", user.getCompanyName());assertEquals("Mary", user.getFirstName());assertEquals("Zheng", user.getLastName());assertEquals(1, user.getUserId().intValue());}@Testpublic void test_toEntity() {User user = new User();user.setCompanyName("test company");user.setFirstName("Mary");user.setLastName("Zheng");user.setUserId(Integer.valueOf(1));Person person = testClass.toUserEntity(user);assertNotNull(user);assertEquals("test company", person.getCompanyName());assertEquals("Mary", person.getfName());assertEquals("Zheng", person.getlName());assertEquals(1, person.getPersonId());}}

Execute it with maven commandmvn test -Dtest=TransformServiceTest and capture the output here.

Output

Running jcg.zheng.demo.service.TransformServiceTestTests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.016 sec - in jcg.zheng.demo.service.TransformServiceTestResults :Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

5.4 MockUserServiceImplTest

UserServiceImpl class has two dependencies:PersonRepository to access database,TransformService to transform thePerson entity toUser domain object. In this step, I will use Mockito to mock these two dependencies and how these two dependencies behave when they are invoked inside theUserServiceImpl class.

  • @Mock – mocks the dependency
  • @InjectMocks – mocks the testing class
  • findById_found – tests thefindById method when the id is available in database by mocking thepersonRepository.findOne method to return a person object.
  • findById_not_found – tests thefindById method when the id is not found in database by mocking thepersonRepository.findOne method to return anull object
  • searchByCompanyName_found – tests searchByCompanyName method when a list of people are found in database by mockingpersonRepository.findByCompany to return a list of person objects
  • searchByCompanyName_not_found – testssearchByCompanyName method when a list of people are not found in database by mockingpersonRepository.findByCompany to return an empty list.
  • deleteById_is_done_by_dao_delete – testsdeleteById by mocking a void method –personRepository .delete
  • mock_db_exception – tests the service will throw exception when database throws exception.

MockUserServiceImplTest.java

package jcg.zheng.demo.service;import static org.junit.Assert.assertEquals;import static org.junit.Assert.assertTrue;import static org.mockito.Mockito.doNothing;import static org.mockito.Mockito.doReturn;import static org.mockito.Mockito.doThrow;import static org.mockito.Mockito.times;import static org.mockito.Mockito.verify;import java.util.ArrayList;import java.util.List;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.mockito.Matchers;import org.mockito.Mock;import org.mockito.runners.MockitoJUnitRunner;import jcg.zheng.demo.entity.Person;import jcg.zheng.demo.exception.UserNotFoundException;import jcg.zheng.demo.repository.PersonRepository;@RunWith(MockitoJUnitRunner.class)public class MockUserServiceImplTest {private static final String MARY = "Mary";private static final String TEST_COMPANY = "Test";private Person person = new Person();@Mockprivate PersonRepository personDao;@InjectMocksprivate UserServiceImpl testClass;@Mockprivate TransformService transformer;private User user = new User();@Testpublic void findById_found() {doReturn(person).when(personDao).findOne(Integer.valueOf(1));doReturn(user).when(transformer).toUserDomain(person);User user = testClass.findById(Integer.valueOf(1));assertEquals(MARY, user.getFirstName());}@Test(expected = UserNotFoundException.class)public void findById_not_found() {doReturn(null).when(personDao).findOne(Integer.valueOf(1));testClass.findById(Integer.valueOf(1));}@Testpublic void searchByCompanyName_found() {List<Person> persons = new ArrayList<>();persons.add(person);doReturn(persons).when(personDao).findByCompany(TEST_COMPANY);doReturn(user).when(transformer).toUserDomain(person);List<User> users = testClass.searchByCompanyName(TEST_COMPANY);assertEquals(1, users.size());assertEquals(MARY, users.get(0).getFirstName());}@Testpublic void searchByCompanyName_not_found() {List<Person> persons = new ArrayList<>();doReturn(persons).when(personDao).findByCompany(TEST_COMPANY);doReturn(user).when(transformer).toUserDomain(person);List<User> users = testClass.searchByCompanyName(TEST_COMPANY);assertTrue(users.isEmpty());}@Testpublic void deleteById_is_done_by_dao_delete() {doNothing().when(personDao).delete(Matchers.any(Integer.class));testClass.deleteById(Integer.valueOf(1));verify(personDao, times(1)).delete(Integer.valueOf(1));;}@Test(expected = Exception.class)public void mock_db_exception() {doThrow(new Exception("bad db")).when(personDao).delete(Matchers.any(Integer.class));}@Beforepublic void setup() {person.setfName(MARY);user.setFirstName(MARY);}}

Execute it with maven commandmvn test -Dtest=MockUserServiceImplTest and capture the output here.

Output

Running jcg.zheng.demo.service.MockUserServiceImplTestTests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.425 sec - in jcg.zheng.demo.service.MockUserServiceImplTestResults :Tests run: 6, Failures: 0, Errors: 0, Skipped: 0

5.5 UserServiceImplTest

Spring test frameworks provides@SpringBootTest which starts the spring context with all the needed objects. In this step, I will create aUserServiceImplTest class which auto-wiresUserService with the following testing methods:

  • findById_throw_exception_when_not_found – expects to throwUserNotfoundException when user is not in database.
  • test_save_findById_searchByCompanyName – tests thesearchByCompanyName first, then it saves a person in database, then it finds the saved person, finally, it deletes it from database.
  • searchByCompanyName_return_empty_when_not_found – returns an empty list when there is no person matches the company name.

Please note that these tests also test thePersonRepository andTransformService. It takes longer time ( 8.99 seconds) than the unit test –MockUserServiceImpl which takes 0.4 seconds.

UserServiceImplTest.java

package jcg.zheng.demo.service;import static org.junit.Assert.assertNotNull;import static org.junit.Assert.assertTrue;import java.util.List;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import jcg.zheng.demo.exception.UserNotFoundException;@RunWith(SpringRunner.class)@SpringBootTestpublic class UserServiceImplTest {@Autowiredprivate UserService userService;@Test(expected = UserNotFoundException.class)public void findById_throw_exception_when_not_found() {userService.findById(Integer.valueOf(-1));}@Testpublic void searchByCompanyName_return_empty_when_not_found() {List<User> found = userService.searchByCompanyName("Test");assertTrue(found.isEmpty());}@Testpublic void test_save_findById_searchByCompanyName() {User user = new User();user.setFirstName("Mary");user.setLastName("Zheng");user.setCompanyName("Test");user = userService.save(user);assertNotNull(user.getUserId());User foundUser = userService.findById(user.getUserId());assertTrue(foundUser.equals(user));userService.deleteById(user.getUserId());List<User> found = userService.searchByCompanyName("Test");assertTrue(found.isEmpty());}}

Execute it with maven commandmvn test -Dtest=UserServiceImplTest and capture the output here.

Output

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.995 sec - in jcg.zheng.demo.service.UserServiceImplTest2020-03-14 16:27:28.967  INFO 140044 --- [       Thread-5] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@4a668b6e: startup date [Sat Mar 14 16:27:21 CDT 2020]; root of context hierarchy2020-03-14 16:27:28.975  INFO 140044 --- [       Thread-5] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'Results :Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

6. Changes

Imaging the application is in use for a while and business requires a change to use a default system user when the given user is not found in the database.

I will update theUserServiceImpl.java class for this change.

UserServiceImplTest.java

package jcg.zheng.demo.service;import java.util.ArrayList;import java.util.List;import javax.transaction.Transactional;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import jcg.zheng.demo.entity.Person;import jcg.zheng.demo.exception.UserNotFoundException;import jcg.zheng.demo.repository.PersonRepository;@Component@Transactionalpublic class UserServiceImpl implements UserService { @Autowired private PersonRepository personDao; @Autowired private TransformService transformer; @Override public void deleteById(Integer personId) { personDao.delete(personId); } @Override public User findById(Integer personId) { Person found = personDao.findOne(personId); if (found == null) { Person defaultPerson = new Person(); defaultPerson.setfName("default"); defaultPerson.setlName("System"); defaultPerson.setCompanyName("Default"); found = defaultPerson; } return transformer.toUserDomain(found); } @Override public User save(User user) { Person saved = personDao.save(transformer.toUserEntity(user)); return transformer.toUserDomain(saved); } @Override public List<User> searchByCompanyName(String companyName) { List<Person> persons = personDao.findByCompany(companyName); List<User> users = new ArrayList<>(); for (Person person : persons) { users.add(transformer.toUserDomain(person)); } return users; }}

After this change, I will see the JUnit test failed atfindById_not_found immediately.

Failed tests:  MockUserServiceImplTest.findById_not_found Expected exception: jcg.zheng.demo.exception.UserNotFoundExceptionTests run: 6, Failures: 1, Errors: 0, Skipped: 0

In this case, I will fix the test case –findById_not_found to not throw theUserNotFoundException.

@Test public void findById_not_found() {doReturn(null).when(personDao).findOne( Matchers.any(Integer.class)); doReturn(user).when(transformer).toUserDomain(Matchers.any(Person.class));User default_user = testClass.findById(Integer.valueOf(1));assertNotNull(default_user); }

7. Unit Testing Tutorial – Summary

In this example, I demonstrated how to write a unit test in Junit, Mockito, and Spring test frameworks. As we have seen here, the Mockito test is faster than the spring Jpa test. Spring test is not truly unit testing as it relies on the spring context.

There are other common testing frameworks which support unit testing:

  • TestNG – similar to Junit and enables customized tests which reads test data from a spreadsheet.
  • EasyMock – similar to Mockito.
  • PowerMock – can mock static methods, constructors, and private methods.

8. Download the Source Code

Download
You can download the full source code of this example here:Java Unit Testing Tutorial
Do you want to know how to develop your skillset to become aJava Rockstar?
Subscribe to our newsletter to start Rockingright now!
To get you started we give you our best selling eBooks forFREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to theTerms andPrivacy Policy

Thank you!

We will contact you soon.

Photo of Mary ZhengMary ZhengMarch 17th, 2020Last Updated: May 25th, 2021
0 2,729 12 minutes read
Photo of Mary Zheng

Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.

    Related Articles

    Bipartite Graph

    Java not equal Example

    January 17th, 2020
    Bipartite Graph

    Java API Tutorial

    October 26th, 2020
    Bipartite Graph

    Java Struct Example

    January 8th, 2020
    Bipartite Graph

    Java Node Example

    November 20th, 2019
    Bipartite Graph

    Java Swing MVC Example

    January 26th, 2016
    Bipartite Graph

    How to call a method in Java

    December 26th, 2019
    Subscribe
    Notify of
    guest
    I agree to theTerms andPrivacy Policy
    The comment form collects your name, email and content to allow us keep track of the comments placed on the website. Please read and accept our website Terms and Privacy Policy to post a comment.

    I agree to theTerms andPrivacy Policy
    The comment form collects your name, email and content to allow us keep track of the comments placed on the website. Please read and accept our website Terms and Privacy Policy to post a comment.