Final method mocking

Viewed 81151

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.

8 Answers

Mockito 2.x now supports final method and final class stubbing.

From the docs:

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.

Mockito can be used to mock final classes or final methods. The problem is, this doesn't come as out of the box feature from Mockito and needs to be configured explicitely.

So, in order to do that,

Create a text file named org.mockito.plugins.MockMaker to the project's src/test/resources/mockito-extensions directory and add a single line of text as below

mock-maker-inline

Once done, you can use the mockito's when method to mock the behaviour like any other regular method.

See detailed examples here

Related