Getting Started with Mocking in Java using Mockito
We all write unit tests but the challenge we face at times is that the unit under test might be dependent on other components. And configuring other components for unit testing is definitely an overkill. Instead we can make use of Mocks in place of the other components and continue with the unit testing. To show how one can use mocks, I have a Data access layer(DAL), basically a class which provides an API for the application to access and modify the data in the data repository. I then unit test the DAL without actually the need to connect to the data repository. The data repository can be a local database or remote database or a file system or any place where we can store and retrieve the data. The use of a DAL class helps us in keeping the data mappers separate from the application code. Lets create a Java project using maven. mvn archetype:generate -DgroupId=info.sanaulla -DartifactId=MockitoDemo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false The above creates a folder MockitoDemo and then creates the entire directory structure for source and test files. Consider the below model class for this example: package info.sanaulla.models; import java.util.List; /** * Model class for the book details. */ public class Book { private String isbn; private String title; private List authors; private String publication; private Integer yearOfPublication; private Integer numberOfPages; private String image; public Book(String isbn, String title, List authors, String publication, Integer yearOfPublication, Integer numberOfPages, String image){ this.isbn = isbn; this.title = title; this.authors = authors; this.publication = publication; this.yearOfPublication = yearOfPublication; this.numberOfPages = numberOfPages; this.image = image; } public String getIsbn() { return isbn; } public String getTitle() { return title; } public List getAuthors() { return authors; } public String getPublication() { return publication; } public Integer getYearOfPublication() { return yearOfPublication; } public Integer getNumberOfPages() { return numberOfPages; } public String getImage() { return image; } } The DAL class for operating on the Book model class is: package info.sanaulla.dal; import info.sanaulla.models.Book; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * API layer for persisting and retrieving the Book objects. */ public class BookDAL { private static BookDAL bookDAL = new BookDAL(); public List getAllBooks(){ return Collections.EMPTY_LIST; } public Book getBook(String isbn){ return null; } public String addBook(Book book){ return book.getIsbn(); } public String updateBook(Book book){ return book.getIsbn(); } public static BookDAL getInstance(){ return bookDAL; } } The DAL layer above currently has no functionality and we are going to unit test that piece of code (TDD). The DAL layer might communicate with a ORM Mapper or Database API which we are not concerned while designing the API. Test Driving the DAL Layer There are lot of frameworks for Unit testing and mocking in Java but for this example I would be picking JUnit for unit testing and Mockito for mocking. We would have to update the dependency in Maven’s pom.xml 4.0.0 info.sanaulla MockitoDemo jar 1.0-SNAPSHOT MockitoDemo http://maven.apache.org junit junit 4.10 test org.mockito mockito-all 1.9.5 test Now lets unit test the BookDAL. During the unit testing we will inject mock data into the BookDAL so that we can complete the testing of the API without depending on the data source. Initially we will have an empty test class: public class BookDALTest { public void setUp() throws Exception { } public void testGetAllBooks() throws Exception { } public void testGetBook() throws Exception { } public void testAddBook() throws Exception { } public void testUpdateBook() throws Exception { } } We will inject the mock BookDAL and mock data in the setUp() as shown below: public class BookDALTest { private static BookDAL mockedBookDAL; private static Book book1; private static Book book2; @BeforeClass public static void setUp(){ //Create mock object of BookDAL mockedBookDAL = mock(BookDAL.class); //Create few instances of Book class. book1 = new Book("8131721019","Compilers Principles", Arrays.asList("D. Jeffrey Ulman","Ravi Sethi", "Alfred V. Aho", "Monica S. Lam"), "Pearson Education Singapore Pte Ltd", 2008,1009,"BOOK_IMAGE"); book2 = new Book("9788183331630","Let Us C 13th Edition", Arrays.asList("Yashavant Kanetkar"),"BPB PUBLICATIONS", 2012,675,"BOOK_IMAGE"); //Stubbing the methods of mocked BookDAL with mocked data. when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2)); when(mockedBookDAL.getBook("8131721019")).thenReturn(book1); when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn()); when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn()); } public void testGetAllBooks() throws Exception {} public void testGetBook() throws Exception {} public void testAddBook() throws Exception {} public void testUpdateBook() throws Exception {} } In the above setUp() method I have: Created a mock object of BookDAL BookDAL mockedBookDAL = mock(BookDAL.class); Stubbed the API of BookDAL with mock data, such that when ever the API is invoked the mocked data is returned. //When getAllBooks() is invoked then return the given data and so on for the other methods. when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2)); when(mockedBookDAL.getBook("8131721019")).thenReturn(book1); when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn()); when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn()); Populating the rest of the tests we get: package info.sanaulla.dal; import info.sanaulla.models.Book; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.List; public class BookDALTest { private static BookDAL mockedBookDAL; private static Book book1; private static Book book2; @BeforeClass public static void setUp(){ mockedBookDAL = mock(BookDAL.class); book1 = new Book("8131721019","Compilers Principles", Arrays.asList("D. Jeffrey Ulman","Ravi Sethi", "Alfred V. Aho", "Monica S. Lam"), "Pearson Education Singapore Pte Ltd", 2008,1009,"BOOK_IMAGE"); book2 = new Book("9788183331630","Let Us C 13th Edition", Arrays.asList("Yashavant Kanetkar"),"BPB PUBLICATIONS", 2012,675,"BOOK_IMAGE"); when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2)); when(mockedBookDAL.getBook("8131721019")).thenReturn(book1); when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn()); when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn()); } @Test public void testGetAllBooks() throws Exception { List allBooks = mockedBookDAL.getAllBooks(); assertEquals(2, allBooks.size()); Book myBook = allBooks.get(0); assertEquals("8131721019", myBook.getIsbn()); assertEquals("Compilers Principles", myBook.getTitle()); assertEquals(4, myBook.getAuthors().size()); assertEquals((Integer)2008, myBook.getYearOfPublication()); assertEquals((Integer) 1009, myBook.getNumberOfPages()); assertEquals("Pearson Education Singapore Pte Ltd", myBook.getPublication()); assertEquals("BOOK_IMAGE", myBook.getImage()); } @Test public void testGetBook(){ String isbn = "8131721019"; Book myBook = mockedBookDAL.getBook(isbn); assertNotNull(myBook); assertEquals(isbn, myBook.getIsbn()); assertEquals("Compilers Principles", myBook.getTitle()); assertEquals(4, myBook.getAuthors().size()); assertEquals("Pearson Education Singapore Pte Ltd", myBook.getPublication()); assertEquals((Integer)2008, myBook.getYearOfPublication()); assertEquals((Integer)1009, myBook.getNumberOfPages()); } @Test public void testAddBook(){ String isbn = mockedBookDAL.addBook(book1); assertNotNull(isbn); assertEquals(book1.getIsbn(), isbn); } @Test public void testUpdateBook(){ String isbn = mockedBookDAL.updateBook(book1); assertNotNull(isbn); assertEquals(book1.getIsbn(), isbn); } } One can run the test by using maven command: mvn test. The output is: ------------------------------------------------------- T E S T S ------------------------------------------------------- Running info.sanaulla.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.029 sec Running info.sanaulla.dal.BookDALTest Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.209 sec Results : Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 So we have been able to test the DAL class without actually configuring the data source by using mocks.
February 26, 2014
·
232,758 Views
·
18 Likes
Comments
Jun 27, 2018 · Duncan Brown
Integrating with Captcha is independent of Spring Security. So your API that verifies the captcha need not be protected by Spring security.
Nov 21, 2017 · Mike Gates
It would have been quite simple. But I wanted to do it without using Spring boot and try it out. And moreover not all of them would want to move to spring boot
Nov 03, 2017 · Sarah Davis
Billions of records I don't honk. But you wouldn't want to index billions of records from db. So you should think of better alternatives.
Aug 24, 2017 · Mike Gates
Which JDK version are u using? Its a new API added in Java 7 and its not deprecated so far even in Java 9 (http://download.java.net/java/jdk9/docs/api/java/nio/file/Path.html)
Aug 23, 2017 · Mike Gates
The text right under the heading - this is added by DZone. My original article never had that (https://sanaulla.info/2017/08/09/getting-to-know-about-java-nio-file-path-1/)
Sorry I didn't notice it.
Aug 23, 2017 · Mike Gates
Thanks a lot. I will update the same with your notes.
Aug 22, 2017 · Mike Gates
Nowhere does the introduction say "Java 9 will be introducing". The introductory paragraph says Java has changed over the versions 7,8 and 9.
And then in the subsequent paragraph, I mention that one of the new features introduced in Java 7.
Aug 22, 2017 · Mike Gates
Its Java 7 to be specific. :) But there is not much awareness about these utility APIs added in Java 7 to support File handling.
Jun 05, 2013 · James Sugrue
I am not very proficient with Groovy and hence I picked Java for my examples. Down the line once I am familiar with it, I might port the same to Groovy and may be compare the two.
Jun 05, 2013 · James Sugrue
I am not very proficient with Groovy and hence I picked Java for my examples. Down the line once I am familiar with it, I might port the same to Groovy and may be compare the two.
Jun 05, 2013 · Mr B Loid
I am not very proficient with Groovy and hence I picked Java for my examples. Down the line once I am familiar with it, I might port the same to Groovy and may be compare the two.
Jun 05, 2013 · Mr B Loid
I am not very proficient with Groovy and hence I picked Java for my examples. Down the line once I am familiar with it, I might port the same to Groovy and may be compare the two.
May 28, 2013 · Tom Fennelly
Great! Will try out and post my experiences. Will also check out the code.
May 28, 2013 · mitchp
I have covered it in different posts.
May 15, 2013 · James Sugrue
Agree, and documentation is what we fail to do most of the times.
May 15, 2013 · Mr B Loid
Agree, and documentation is what we fail to do most of the times.
May 15, 2013 · Mr B Loid
Agree, and documentation is what we fail to do most of the times.
May 15, 2013 · James Sugrue
Agree, and documentation is what we fail to do most of the times.
May 15, 2013 · Alexander Artemenko
Cool! May be I should add it to my post. Can I?
May 15, 2013 · Alexander Artemenko
Cool! May be I should add it to my post. Can I?
May 14, 2013 · Alexander Artemenko
Agree that we can put it in an Util.
I got another approach using Google Guava as a comment on my blog.
May 14, 2013 · Alexander Artemenko
Agree that we can put it in an Util.
I got another approach using Google Guava as a comment on my blog.
May 14, 2013 · Alexander Artemenko
I never thought of this. Really cool. Thanks for sharing it!
May 14, 2013 · Alexander Artemenko
I never thought of this. Really cool. Thanks for sharing it!
May 12, 2013 · Alvin Ashcraft
the support for lambda expressions should have been there in the language quite sometime back- may be in the anonymous inner class time frame. But functional programming had not gone mainstream. But off late there has been a lot of focus on functional programming and lot of the concepts in functional programming help in writing good concurrent code.
Its always important to identify where to fit in the feature and how to use it. The Java 8 release was delayed due to the importance given to the security fixes. Apart from lambda expressions there are quite a lot features in Java 8 which I am not aware of. And I am sure there would be performance related features aiming the quality of the product.
May 12, 2013 · Alvin Ashcraft
the support for lambda expressions should have been there in the language quite sometime back- may be in the anonymous inner class time frame. But functional programming had not gone mainstream. But off late there has been a lot of focus on functional programming and lot of the concepts in functional programming help in writing good concurrent code.
Its always important to identify where to fit in the feature and how to use it. The Java 8 release was delayed due to the importance given to the security fixes. Apart from lambda expressions there are quite a lot features in Java 8 which I am not aware of. And I am sure there would be performance related features aiming the quality of the product.
Mar 24, 2013 · Mr B Loid
The reply for this would be same as the one posted here. New languages being introduced learn from the past languages and keep evolving. But something coming into Java would be useful for enterprises who have their investment in Java. And convincing such enterprises to use Scala is not always an easy. For that matter enterprises picking Java 8 for immediate development is another thing that is not possible.
Mar 24, 2013 · Mr B Loid
The reply for this would be same as the one posted here. New languages being introduced learn from the past languages and keep evolving. But something coming into Java would be useful for enterprises who have their investment in Java. And convincing such enterprises to use Scala is not always an easy. For that matter enterprises picking Java 8 for immediate development is another thing that is not possible.
Mar 24, 2013 · James Sugrue
The reply for this would be same as the one posted here. New languages being introduced learn from the past languages and keep evolving. But something coming into Java would be useful for enterprises who have their investment in Java. And convincing such enterprises to use Scala is not always an easy. For that matter enterprises picking Java 8 for immediate development is another thing that is not possible.
Mar 24, 2013 · Mr B Loid
The reply for this would be same as the one posted here. New languages being introduced learn from the past languages and keep evolving. But something coming into Java would be useful for enterprises who have their investment in Java. And convincing such enterprises to use Scala is not always an easy. For that matter enterprises picking Java 8 for immediate development is another thing that is not possible.
Mar 24, 2013 · James Sugrue
The reply for this would be same as the one posted here. New languages being introduced learn from the past languages and keep evolving. But something coming into Java would be useful for enterprises who have their investment in Java. And convincing such enterprises to use Scala is not always an easy. For that matter enterprises picking Java 8 for immediate development is another thing that is not possible.
Mar 24, 2013 · James Sugrue
The reply for this would be same as the one posted here. New languages being introduced learn from the past languages and keep evolving. But something coming into Java would be useful for enterprises who have their investment in Java. And convincing such enterprises to use Scala is not always an easy. For that matter enterprises picking Java 8 for immediate development is another thing that is not possible.
Mar 24, 2013 · James Sugrue
Mar 24, 2013 · Mr B Loid
Mar 24, 2013 · Mr B Loid
Mar 24, 2013 · James Sugrue
May 12, 2012 · Yong Mook Kim
Mar 29, 2012 · Ahmad Mushtaq
Yes this was a very obvious example, as pointed in my other comment there has been lot of research put in this and there by a tool was developed (an eclipse plugin) as an implementation of the research.
The research done on this is a pretty good read
Mar 29, 2012 · Ahmad Mushtaq
Yes this was a very obvious example, as pointed in my other comment there has been lot of research put in this and there by a tool was developed (an eclipse plugin) as an implementation of the research.
The research done on this is a pretty good read
Mar 29, 2012 · Ahmad Mushtaq
Yes this was a very obvious example, as pointed in my other comment there has been lot of research put in this and there by a tool was developed (an eclipse plugin) as an implementation of the research.
The research done on this is a pretty good read
Mar 29, 2012 · Ahmad Mushtaq
There's lot of research involved in how JDeodrant identifies the code smells. They have research papers linked from their project site. I was going through 1 (about Extract method) and its more of what we do manually which is being automated. I havent got time to read other papers on this.
I am not sure how much of industry applicable it can be, I was curious as to how they would do the refactoring ( also driven by the fact that I was reading Martin Fowlers Refactoring ;) ) so thought of trying out the tool. As pointed out a better example would have been much useful and also the fact that other options for refactoring were not tried.
Mar 29, 2012 · Ahmad Mushtaq
There's lot of research involved in how JDeodrant identifies the code smells. They have research papers linked from their project site. I was going through 1 (about Extract method) and its more of what we do manually which is being automated. I havent got time to read other papers on this.
I am not sure how much of industry applicable it can be, I was curious as to how they would do the refactoring ( also driven by the fact that I was reading Martin Fowlers Refactoring ;) ) so thought of trying out the tool. As pointed out a better example would have been much useful and also the fact that other options for refactoring were not tried.
Mar 29, 2012 · Ahmad Mushtaq
There's lot of research involved in how JDeodrant identifies the code smells. They have research papers linked from their project site. I was going through 1 (about Extract method) and its more of what we do manually which is being automated. I havent got time to read other papers on this.
I am not sure how much of industry applicable it can be, I was curious as to how they would do the refactoring ( also driven by the fact that I was reading Martin Fowlers Refactoring ;) ) so thought of trying out the tool. As pointed out a better example would have been much useful and also the fact that other options for refactoring were not tried.
Aug 05, 2011 · Vashu Singh
Jun 17, 2011 · Dev Stonez