How to mock a final class with mockito

后端 未结 25 1109
日久生厌
日久生厌 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:40

    If you trying to run unit-test under the test folder, the top solution is fine. Just follow it adding an extension.

    But if you want to run it with android related class like context or activity which is under androidtest folder, the answer is for you.

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

    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

    ...

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

    add this in your gradle file:

    testImplementation 'org.mockito:mockito-inline:2.13.0'
    

    this is a configuration to make mockito work with final classes

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

    Mocking final classes is not supported for mockito-android as per this GitHub issue. You should use Mockk instead for this.

    For both unit test and ui test, you can use Mockk with no problem.

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

    Time saver for people who are facing the same issue (Mockito + Final Class) on Android + Kotlin. As in Kotlin classes are final by default. I found a solution in one of Google Android samples with Architecture component. Solution picked from here : https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample

    Create following annotations :

    /**
     * This annotation allows us to open some classes for mocking purposes while they are final in
     * release builds.
     */
    @Target(AnnotationTarget.ANNOTATION_CLASS)
    annotation class OpenClass
    
    /**
     * Annotate a class with [OpenForTesting] if you want it to be extendable in debug builds.
     */
    @OpenClass
    @Target(AnnotationTarget.CLASS)
    annotation class OpenForTesting
    

    Modify your gradle file. Take example from here : https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/build.gradle

    apply plugin: 'kotlin-allopen'
    
    allOpen {
        // allows mocking for classes w/o directly opening them for release builds
        annotation 'com.android.example.github.testing.OpenClass'
    }
    

    Now you can annotate any class to make it open for testing :

    @OpenForTesting
    class RepoRepository 
    
    0 讨论(0)
  • 2020-11-22 16:51

    For final class add below to mock and call static or non static.

    1- add this in class level @SuppressStatucInitializationFor(value ={class name with package})
    2- PowerMockito.mockStatic(classname.class) will mock class
    3- then use your when statement to return mock object when calling method of this class.

    Enjoy

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