Final method mocking
Solution 1
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.
Solution 2
From the Mockito 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.
Solution 3
You can use Powermock together with Mockito, then you do not need to subclass B.class. Just add this to the top of your test class
@RunWith(PowerMockRunner.class)
@PrepareForTest(B.class)
@PrepareForTest
instructs Powermock to instrument B.class to make the final and static methods mockable. A disadvantage of this approach is that you must use PowerMockRunner which precludes use of other test runners such as the Spring test runner.
Solution 4
Mockito 2 now supports mocking final methods but that's an "incubating" feature. It requires some steps to activate it which are described here: https://github.com/mockito/mockito/wiki/What's-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
Solution 5
Mockito 2.x now supports final method and final class stubbing.
Mocking of final classes and methods is an incubating, opt-in feature. This feature has to be explicitly activated by creating the file
src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
containing a single line:
mock-maker-inline
After you create this file you can do:
final class FinalClass { final String finalMethod() { return "something"; } } FinalClass concrete = new FinalClass(); FinalClass mock = mock(FinalClass.class); given(mock.finalMethod()).willReturn("not anymore"); assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());
In subsequent milestones, the team will bring a programmatic way of using this feature. We will identify and provide support for all unmockable scenarios.
Comments
-
Stan Kurilin almost 2 years
I need mock some class with final method using mockito. I have wrote something like this
@Test public void test() { B b = mock(B.class); doReturn("bar called").when(b).bar(); assertEquals("must be \"overrided\"", "bar called", b.bar()); //bla-bla } class B { public final String bar() { return "fail"; } }
But it fails. I tried some "hack" and it works.
@Test public void hackTest() { class NewB extends B { public String barForTest() { return bar(); } } NewB b = mock(NewB.class); doReturn("bar called").when(b).barForTest(); assertEquals("must be \"overrided\"", "bar called", b.barForTest()); }
It works, but "smells".
So, Where is the right way?
Thanks.
-
Jan Zyka over 8 yearsThis doesn't work for me. Added as adviced but still getting
NullPointerException
in the same way when not using the@RunWith
and@PrepareForTest
. Seems the class hasn't been intrumented for some reason. -
mike rodent over 7 yearsThanks for this. Do you happen to know what the current state of
verify
ingfinal
methods is? Obviously I had a look in that page but it didn't seem to say anything... -
WindRider over 7 yearsI'm not sure. Check out this: stackoverflow.com/questions/14292863/…
-
Vladyslav Nikolaiev about 6 yearsLink seems to be broken
-
Cedric Reichenbach almost 6 yearsYou should then mock with
PowerMockito.mock
, notMockito.mock
. -
Cypress Frankenfeld over 5 yearsNow that is only listed under Mockito 1.x Specific Limitations github.com/mockito/mockito/wiki/…. Perhaps you can mock final methods in Mockito 2.x?
-
Cypress Frankenfeld over 5 yearsYes, I just checked and you can now mock final methods in Mockito 2.x. I added how to do so in an answer: stackoverflow.com/a/53837478/382892
-
Cypress Frankenfeld about 5 yearsThis is out of date. Mockito 2.x supports final method mocking now (see the docs: github.com/mockito/mockito/wiki/…)
-
Cypress Frankenfeld about 5 yearsMockito now supports final method mocking in Mockito 2.x github.com/mockito/mockito/wiki/…
-
vmaldosan about 5 yearsI tried this approach with SpringRunner and worked for the specific use case I wanted, but making all mocks in the project inlined broke multiple tests in the project, all of them run with MockitoJUnitRunner. I could provide more details if somebody wanted to investigate further. For now I'll wait until that functionality is incorporated into the Mockito code base without altering all the mocks of the project.
-
Noel Yap over 4 yearsThis answer is obsolete. Mockito now supports mocking final methods. See baeldung.com/mockito-final.
-
ThomasW about 4 yearsNote that this method doesn't work for Android. github.com/mockito/mockito/issues/1173
-
spottedmahn about 4 years
-
Snekse about 4 yearsBe warned, this may slow down your tests