15 Mockito Interview Questions and Answers
Prepare for your Java interview with this guide on Mockito, featuring common questions and answers to help you demonstrate your testing skills.
Prepare for your Java interview with this guide on Mockito, featuring common questions and answers to help you demonstrate your testing skills.
Mockito is a popular mocking framework for unit tests in Java. It allows developers to create and configure mock objects, making it easier to isolate the code being tested and ensure that unit tests are both reliable and maintainable. Mockito’s simplicity and flexibility have made it a go-to tool for developers aiming to write clean, efficient, and effective tests.
This article provides a curated selection of Mockito interview questions designed to help you demonstrate your proficiency with the framework. By familiarizing yourself with these questions and their answers, you’ll be better prepared to showcase your understanding of Mockito’s capabilities and best practices during your interview.
Mockito is a Java-based framework used for creating mock objects in unit tests. It allows developers to isolate the unit of work being tested by simulating the behavior of dependencies, enabling a focus on testing the logic of the code without external influences.
Mockito is useful for:
Example:
import static org.mockito.Mockito.*; public class UserServiceTest { @Test public void testGetUser() { UserRepository mockRepository = mock(UserRepository.class); when(mockRepository.findUserById(1)).thenReturn(new User(1, "John Doe")); UserService userService = new UserService(mockRepository); User user = userService.getUser(1); verify(mockRepository).findUserById(1); assertEquals("John Doe", user.getName()); } }
Mock objects simulate the behavior of real objects, allowing you to test a class in isolation by providing controlled responses to method calls. To create a mock object using Mockito, use the Mockito.mock()
method, which takes a class type as an argument and returns a mock instance.
Example:
import static org.mockito.Mockito.*; public class Example { public static void main(String[] args) { List<String> mockedList = mock(List.class); when(mockedList.get(0)).thenReturn("Hello, Mockito!"); System.out.println(mockedList.get(0)); // Output: Hello, Mockito! } }
@Mock
and @InjectMocks
.In Mockito, @Mock
and @InjectMocks
are annotations for creating mock objects and injecting them into the class under test.
@Mock
: Creates and injects mock objects, typically for dependencies.@InjectMocks
: Creates an instance of the class under test and injects the mock objects into it.Example:
public class Service { private Repository repository; public Service(Repository repository) { this.repository = repository; } public String getData() { return repository.fetchData(); } } @RunWith(MockitoJUnitRunner.class) public class ServiceTest { @Mock private Repository repository; @InjectMocks private Service service; @Test public void testGetData() { when(repository.fetchData()).thenReturn("mocked data"); String result = service.getData(); assertEquals("mocked data", result); } }
Verifying interactions with a mock object ensures that expected methods are called with the correct parameters. This is useful in unit testing to confirm expected behavior. Mockito provides methods like verify()
to check interactions.
Example:
import static org.mockito.Mockito.*; public class MockitoExample { public static void main(String[] args) { List<String> mockedList = mock(List.class); mockedList.add("one"); mockedList.clear(); verify(mockedList).add("one"); verify(mockedList).clear(); } }
Stubbing in Mockito controls the behavior of methods in mock objects, allowing you to specify return values for method calls. Use the when
and thenReturn
methods to stub a method.
Example:
import static org.mockito.Mockito.*; public class Example { public static void main(String[] args) { MyClass myClass = mock(MyClass.class); when(myClass.myMethod()).thenReturn("stubbed value"); String result = myClass.myMethod(); System.out.println(result); // Output: stubbed value } } class MyClass { public String myMethod() { return "original value"; } }
To simulate exceptions in Mockito, use the thenThrow
method. This is useful for testing exception handling.
Example:
import static org.mockito.Mockito.*; public class ExceptionHandlingTest { public static void main(String[] args) { List mockedList = mock(List.class); when(mockedList.get(0)).thenThrow(new RuntimeException("Exception occurred")); try { mockedList.get(0); } catch (RuntimeException e) { System.out.println(e.getMessage()); } } }
spy
.A spy
in Mockito creates a partial mock of an object, allowing you to stub or verify specific methods while keeping the original behavior for others.
Example:
import static org.mockito.Mockito.*; import java.util.ArrayList; import java.util.List; public class MockitoSpyExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); List<String> spyList = spy(list); spyList.add("one"); spyList.add("two"); when(spyList.get(0)).thenReturn("stubbed"); System.out.println(spyList.get(0)); // Output: stubbed System.out.println(spyList.get(1)); // Output: two verify(spyList).add("one"); verify(spyList).add("two"); } }
To verify the number of times a method was called, use the verify
method with times
.
Example:
import static org.mockito.Mockito.*; public class ExampleTest { public static void main(String[] args) { List<String> mockedList = mock(List.class); mockedList.add("one"); mockedList.add("one"); mockedList.add("two"); verify(mockedList, times(2)).add("one"); verify(mockedList, times(1)).add("two"); verify(mockedList, never()).add("three"); } }
InOrder
verification.InOrder
verification checks that interactions with mock objects occur in a specific sequence.
Example:
import static org.mockito.Mockito.*; public class InOrderExample { public static void main(String[] args) { List<String> mockedList = mock(List.class); mockedList.add("first"); mockedList.add("second"); InOrder inOrder = inOrder(mockedList); inOrder.verify(mockedList).add("first"); inOrder.verify(mockedList).add("second"); } }
doReturn
, doThrow
, doAnswer
, etc.Mockito provides methods like doReturn
, doThrow
, and doAnswer
to control mock behavior.
Example:
import static org.mockito.Mockito.*; public class MockitoExample { public static void main(String[] args) { List<String> mockList = mock(List.class); doReturn("Mocked Value").when(mockList).get(0); System.out.println(mockList.get(0)); // Output: Mocked Value doThrow(new RuntimeException("Exception")).when(mockList).get(1); try { mockList.get(1); } catch (RuntimeException e) { System.out.println(e.getMessage()); // Output: Exception } doAnswer(invocation -> { Object arg0 = invocation.getArgument(0); return "Hello " + arg0; }).when(mockList).get(2); System.out.println(mockList.get(2)); // Output: Hello 2 } }
To integrate Mockito with JUnit 5, use the Mockito extension to enable annotations like @Mock and @InjectMocks.
Example:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; @ExtendWith(MockitoExtension.class) public class MyServiceTest { @Mock private MyRepository myRepository; @InjectMocks private MyService myService; @Test void testServiceMethod() { when(myRepository.getData()).thenReturn("Mock Data"); String result = myService.processData(); assertEquals("Processed Mock Data", result); } }
Mocking creates a mock object that mimics a real object, useful for isolating the unit of work being tested. Spying involves creating a spy object that wraps around a real object, allowing you to call actual methods while controlling or verifying specific interactions.
Example:
import static org.mockito.Mockito.*; public class MockitoExample { public static void main(String[] args) { // Mocking List<String> mockedList = mock(List.class); mockedList.add("one"); verify(mockedList).add("one"); when(mockedList.size()).thenReturn(100); System.out.println(mockedList.size()); // Prints 100 // Spying List<String> spyList = spy(new ArrayList<>()); spyList.add("one"); verify(spyList).add("one"); when(spyList.size()).thenReturn(100); System.out.println(spyList.size()); // Prints 100 } }
Mockito has limitations:
MockitoExtension
in JUnit 5.MockitoExtension
in JUnit 5 enables Mockito annotations, simplifying mock setup and dependency injection, making test code cleaner.
Example:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class MyServiceTest { @Mock private MyRepository myRepository; @InjectMocks private MyService myService; @Test void testServiceMethod() { when(myRepository.getData()).thenReturn("Mock Data"); String result = myService.processData(); assertEquals("Processed Mock Data", result); } }
Custom answers in Mockito allow you to define complex behavior for mocked methods by implementing the Answer
interface.
Example:
import static org.mockito.Mockito.*; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; public class CustomAnswerExample { public static void main(String[] args) { List<String> mockedList = mock(List.class); when(mockedList.get(anyInt())).thenAnswer(new Answer<String>() { @Override public String answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); Integer index = (Integer) args[0]; return "Element at index " + index; } }); System.out.println(mockedList.get(0)); // Output: Element at index 0 System.out.println(mockedList.get(1)); // Output: Element at index 1 } }