January 8, 2023August 19, 2024 Getting Started With Mockito and JUnit In this mockito tutorial, learn the fundamentals of the mockito framework, and how to write JUnit tests along with mockito with an example. 1. Mockito Introduction Mockito is an open-source framework that allows us to easily create test doubles (mocks). A ‘test double‘ is a generic term for any case where we replace a production object for testing purposes. In mockito, we generally work with the following kinds of test doubles. Stubs – are objects that have predefined return values to the method executions made during the test. Spies – are objects that are similar to stubs, but they additionally record the stats of how they were executed. Mocks – are objects that have return values to method executions made during the test and has recorded expectations of these executions. Mocks can throw an exception if they receive a call they don’t expect and are checked during verification to ensure they got all the calls they were expecting. We can mock both interfaces and classes in the test class. Mockito also helps to produce minimum boilerplate code if we use the using mockito annotations. Once created, a mock will remember all interactions. Then we can selectively verify whatever interactions we are interested in. 2. Mockito Setup 2.1. Maven To add mockito into the project, we can add the latest mockito version by any means i.e. Maven, Gradle or jar file. <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> testCompile group: 'org.mockito', name: 'mockito-core', version: '4.11.1' 2.2. Bootstrapping with JUnit To process Mockito annotations with JUnit 5, we need to use MockitoExtention as follows: @ExtendWith(MockitoExtension.class) public class ApplicationTest { //code } For legacy JUnit 4, we can use either MockitoJUnitRunner or MockitoRule classes. @RunWith(MockitoJUnitRunner.class) public class ApplicationTest { //code } public class ApplicationTest { @Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);//code } The strict stubbing ensures clean tests, reduces test code duplication, and improves debuggability. The test fails early when the code under test invokes a stubbed method with different arguments, or unused stubs are present. Alternatively, we can programmatically bootstrap mockito using openMocks() method somewhere in the base class or a test runner. This method initializes fields annotated with Mockito annotations @Mock, @Spy, @Captor, @InjectMocks. The previously used initMocks() method is now deprecated. public class ApplicationTest { MockitoAnnotations.openMocks(this); } 3. Mockito Annotations Before hitting the keyboard to write unit tests, let’s quickly go through the useful mockito annotations. @Mock is used for mock creation. It makes the test class more readable. @Spy is used to create a spy instance. We can use it instead spy(Object) method. @InjectMocks is used to instantiate the tested object automatically and inject all the @Mock or @Spy annotated field dependencies into it (if applicable). It is worth knowing the difference between @Mock and @InitMocks annotations. @Captor is used to create an argument captor. public class ApplicationTest { @Mock Depedency mock; @InjectMocks Service codeUnderTest; } 4. Mockito Demo 4.1. System Under Test To demo the Mockito syntax, we have created a typical usecase where a RecordService invokes RecordDao to save a Record. The RecordService uses a SequenceGenerator class to get the next record id. 4.2. Test Demo To test RecordService.saveRecord() method, we need to inject RecordDao and SequenceGenerator as dependencies in it. For this, we are using @Mock and @InjectMocks annotations. The @ExtendWith(MockitoExtension.class) starts the bootstrapping process and injects the mocks into the service instance. We use when(…).then(…) methods to record the expectations from mock objects, and we verify these expectations, after the application code execution finishes, using the verify() method calls. Finally, we can use additional JUnit assertions for additional validations, if any. @ExtendWith(MockitoExtension.class) public class MockitoHelloTest { @Mock RecordDao mockDao; @Mock NotificationService mockNotification; @Mock SequenceGenerator mockGenerator; @InjectMocks RecordService service; @Test public void testSaveRecord() { Record record = new Record(); record.setName("Test Record"); when(mockGenerator.getNext()).thenReturn(100L); when(mockDao.saveRecord(record)).thenReturn(record); Record savedRecord = service.saveRecord(record); verify(mockGenerator, times(1)).getNext(); verify(mockDao, times(1)).saveRecord(any(Record.class)); assertEquals("Test Record", savedRecord.getName()); assertEquals(100L, savedRecord.getId()); } } Mockito Testing Framework aneesh mistry tutorialaneesh tutorialin28minutes tutorialjava tutorialjunitjunit 5 tutorialjunit mockitojunit mockito tutorialjunit tutorialjunit tutorial for beginnersmockitomockito junit tutorialmockito junit tutorial java brainsmockito junit tutorial spring bootmockito maven tutorialmockito spring tutorialmockito tutorialmockito tutorial for beginnersmockito with junit 5 tutorialsoftware tutorialstep by step tutorialtutorial