Mockito 3 Mock Final Class and Method

Mockito by default can mock interface, abstract class, and normal class, but it cannot mock the final class and final method. if tried then it will give an error.

Mockito cannot mock/spy because :
 - final class

Although Mockito does support mocking of final classes and methods with the help of the mock maker extension It is disabled by default. the mock maker can be activated explicitly by the Mockito extension mechanism.

By default, Mockito creates a new class to represent a mock, but The mock maker extension uses both Java instrumentation API and sub-classing. hence it becomes possible to mock final types and methods. Mockito Privodes 2 ways to enable mock maker extension.

  • MockMaker config file
  • Mockito-inline artifact

MockMaker config file

In older versions of Mockito mock maker extension could be activated by creating a config file org.mockito.plugins.MockMaker in resources/mockito-extensions directory.

mock-maker-inline
package com.example.mokito3.sujan;

public class AppleRepo {
    final String saveApple(String apple) {
        String appleString = "i have " + apple + " apple";
        return appleString;
    }
}
package com.example.mokito3.sujan;

public final class AppleService {
    String saveApple(String apple) {
        String appleString = "i love " + apple + " apple";
        return appleString;
    }
}
package com.example.mokito3.sujan;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
    @Mock
    private AppleService appleService;
    @Mock
    private AppleRepo appleRepo;

    @Test
    void saveAppleFinalClassMockTest() {
        when(appleService.saveApple("Macintosh")).thenReturn("i eat apple");
        String apple = appleService.saveApple("Macintosh");
        verify(appleService).saveApple("Macintosh");
        assertEquals("i eat apple", apple);
    }

    @Test
    void saveAppleFinalMethodMockTest() {
        when(appleRepo.saveApple("Macintosh")).thenReturn("i eat apple");
        String apple = appleRepo.saveApple("Macintosh");
        verify(appleRepo).saveApple("Macintosh");
        assertEquals("i eat apple", apple);
    }
}
plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'

repositories { jcenter() }
dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
    testCompile 'org.mockito:mockito-junit-jupiter:3.4.4'
}
test {
    useJUnitPlatform()
}

mockito-inline artifact

Creating a separate config file just to enable an extension is boilerplate code. To make it more convenient latest versions of Mockito provide mockito-inline artifact in which the mock maker is preconfigured.

mockito-inline artifact artifact will be discontinued once final classes and methods mocking get integrated into the default mock maker.

package com.example.mokito3.sujan;

public final class AppleService {
    String saveApple(String apple) {
        String appleString = "i love " + apple + " apple";
        return appleString;
    }
}
package com.example.mokito3.sujan;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
    @Mock
    private AppleService appleService;
    @Mock
    private AppleRepo appleRepo;

    @Test
    void saveAppleFinalClassMockTest() {
        when(appleService.saveApple("Macintosh")).thenReturn("i eat apple");
        String apple = appleService.saveApple("Macintosh");
        verify(appleService).saveApple("Macintosh");
        assertEquals("i eat apple", apple);
    }

    @Test
    void saveAppleFinalMethodMockTest() {
        when(appleRepo.saveApple("Macintosh")).thenReturn("i eat apple");
        String apple = appleRepo.saveApple("Macintosh");
        verify(appleRepo).saveApple("Macintosh");
        assertEquals("i eat apple", apple);
    }
}
plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'

repositories { jcenter() }
dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
    testCompile 'org.mockito:mockito-junit-jupiter:3.4.4'
    testCompile 'org.mockito:mockito-inline:3.4.4'
}
test {
    useJUnitPlatform()
}

 

follow us on