How to mock a final class with mockito

后端 未结 25 1108
日久生厌
日久生厌 2020-11-22 16:35

I have a final class, something like this:

public final class RainOnTrees{

   public void startRain(){

        // some code here
   }
}

I

相关标签:
25条回答
  • 2020-11-22 16:52

    Yes same problem here, we cannot mock a final class with Mockito. To be accurate, Mockito cannot mock/spy following:

    • final classes
    • anonymous classes
    • primitive types

    But using a wrapper class seems to me a big price to pay, so get PowerMockito instead.

    0 讨论(0)
  • 2020-11-22 16:52

    Add these dependencies for run mockito successfully :

    testImplementation 'org.mockito:mockito-core:2.24.5'
    testImplementation "org.mockito:mockito-inline:2.24.5"

    0 讨论(0)
  • 2020-11-22 16:52

    For us, it was because we excluded mockito-inline from koin-test. One gradle module actually needed this and for reason only failed on release builds (debug builds in the IDE worked) :-P

    0 讨论(0)
  • 2020-11-22 16:56

    In Mockito 3 and more I have the same problem and fixed it as from this link

    Mock Final Classes and Methods with Mockito as follow

    Before Mockito can be used for mocking final classes and methods, it needs to be > configured.

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

    mock-maker-inline
    

    Mockito checks the extensions directory for configuration files when it is loaded. This file enables the mocking of final methods and classes.

    0 讨论(0)
  • 2020-11-22 16:56

    This can be done if you are using Mockito2, with the new incubating feature which supports mocking of final classes & methods.

    Key points to note:
    1. Create a simple file with the name “org.mockito.plugins.MockMaker” and place it in a folder named “mockito-extensions”. This folder should be made available on the classpath.
    2. The content of the file created above should be a single line as given below:
    mock-maker-inline

    The above two steps are required in order to activate the mockito extension mechanism and use this opt-in feature.

    Sample classes are as follows:-

    FinalClass.java

    public final class FinalClass {
    
    public final String hello(){
        System.out.println("Final class says Hello!!!");
        return "0";
    }
    

    }

    Foo.java

    public class Foo {
    
    public String executeFinal(FinalClass finalClass){
        return finalClass.hello();
    }
    

    }

    FooTest.java

    public class FooTest {
    
    @Test
    public void testFinalClass(){
        // Instantiate the class under test.
        Foo foo = new Foo();
    
        // Instantiate the external dependency
        FinalClass realFinalClass = new FinalClass();
    
        // Create mock object for the final class. 
        FinalClass mockedFinalClass = mock(FinalClass.class);
    
        // Provide stub for mocked object.
        when(mockedFinalClass.hello()).thenReturn("1");
    
        // assert
        assertEquals("0", foo.executeFinal(realFinalClass));
        assertEquals("1", foo.executeFinal(mockedFinalClass));
    
    }
    

    }

    Hope it helps.

    Complete article present here mocking-the-unmockable.

    0 讨论(0)
  • 2020-11-22 16:56

    Solutions provided by RC and Luigi R. Viggiano together is possibly the best idea.

    Although Mockito cannot, by design, mock final classes, the delegation approach is possible. This has its advantages:

    1. You are not forced to change your class to non-final if that is what your API intends in the first place (final classes have their benefits).
    2. You are testing the possibility of a decoration around your API.

    In your test case, you deliberately forward the calls to the system under test. Hence, by design, your decoration does not do anything.

    Hence you test can also demonstrate that the user can only decorate the API instead of extending it.

    On a more subjective note: I prefer keeping the frameworks to a minimum, which is why JUnit and Mockito are usually sufficient for me. In fact, restricting this way sometimes forces me to refactor for good as well.

    0 讨论(0)
提交回复
热议问题