Final method mocking
There is no support for mocking final methods in Mockito.
As Jon Skeet commented you should be looking for a way to avoid the dependency on the final method. That said, there are some ways out through bytecode manipulation (e.g. with PowerMock)
A comparison between Mockito and PowerMock will explain things in detail.
How to mock a final class with mockito
Mocking final/static classes/methods is possible with Mockito v2 only.
add this in your gradle file:
testImplementation 'org.mockito:mockito-inline:2.13.0'
This is not possible with Mockito v1, from the Mockito FAQ:
What are the limitations of Mockito
Needs java 1.5+
Cannot mock final classes
...
Nullpointer Exception for mocking final method
The NullPointerException
comes from the invocation of the getAsMap
method.
Using Mockito.doReturn(map).when(aggs).getAsMap();
instead should solve that issue.
However there seems to be a bug in PowerMockito
as writing it like this is not supposed to trigger the invocation of the getAsMap()
method (which still happens).
I suggest you create a bug ticket in their bugtracker for this issue.
If you enable final mocking for Mockito
(see here) running the test is successful.
@RunWith(MockitoJUnitRunner.class)
public class TestExample {
@Test
public void testMyMethod() {
Aggregations aggs = Mockito.mock(Aggregations.class);
Cardinality cardinality = Mockito.mock(Cardinality.class);
Map<String, Aggregation> map = new HashMap<String, Aggregation>();
map.put("sample", cardinality);
Mockito.doReturn(map).when(aggs).getAsMap();
Assert.assertEquals(map, aggs.getAsMap());
}
}
Another option might be to work with a real Aggregations
object instead:
@Test
public void testMyMethod() {
Cardinality cardinality = Mockito.mock(Cardinality.class);
Mockito.when(cardinality.getName()).thenReturn("sample");
List<Aggregation> list = new ArrayList<>();
list.add(cardinality);
Aggregations aggs = new Aggregations(list);
Map<String, Aggregation> map = aggs.getAsMap();
Assert.assertEquals(1, map.size());
Assert.assertEquals(cardinality, map.get("sample"));
}
Mock an inherited final method
From Mockito's FAQ:
What are the limitations of Mockito?
[...]
- Cannot mock final methods - their real behavior is executed without any exception. Mockito cannot warn you about mocking final methods so be vigilant.
[...]
For this, you need an extension like PowerMock. See this question for a working example. A throughout description can be found in PowerMock's documentation
Mock a method that's inside a final class using Mockito
Try to write a testable code. Example in your case, Your class is final and cannot be mocked, then your class can implement an interface, then you can absolutely mock the methods of the interface.
Your class is final and cannot be mocked
Why? Because a final class cannot be extended. By mocking a class/interface, the technique behind is it creates a subclass extends/implements the class/interface. Then if your class prevents extending by having final
, you cannot mock it.
Note: you can use some power libs to mock final class (e.g. - powermockito), but I would not recommend this.
Related Topics
Reversing a Linked List in Java, Recursively
When Should I Use File.Separator and When File.Pathseparator
Double Checked Locking in Singleton
In Java, What Is a Shallow Copy
Date Format Mapping to JSON Jackson
Break or Return from Java 8 Stream Foreach
How to Replace the Awt Eventqueue with Own Implementation
Scanner Nosuchelementexception
Sorting Java Objects Using Multiple Keys
Jcombobox Selection Change Listener
How to Select a Dropdown Value in Selenium Webdriver Using Java
Listener Placement Adhering to the Traditional (Non-Mediator) MVC Pattern
Draw a Circle with a Radius and Points Around the Edge