How to mock a final class with mockito

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

    Give this a try:

    Mockito.mock(SomeMockableType.class,AdditionalAnswers.delegatesTo(someInstanceThatIsNotMockableOrSpyable));
    

    It worked for me. "SomeMockableType.class" is the parent class of what you want to mock or spy, and someInstanceThatIsNotMockableOrSpyable is the actual class that you want to mock or spy.

    For more details have a look here

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

    As others have stated, this won't work out of the box with Mockito. I would suggest using reflection to set the specific fields on the object that is being used by the code under test. If you find yourself doing this a lot, you can wrap this functionality in a library.

    As an aside, if you are the one marking classes final, stop doing that. I ran across this question because I am working with an API where everything was marked final to prevent my legitimate need for extension (mocking), and I wish that the developer had not assumed that I would never need to extend the class.

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

    I guess you made it final because you want to prevent other classes from extending RainOnTrees. As Effective Java suggests (item 15), there's another way to keep a class close for extension without making it final:

    1. Remove the final keyword;

    2. Make its constructor private. No class will be able to extend it because it won't be able to call the super constructor;

    3. Create a static factory method to instantiate your class.

      // No more final keyword here.
      public class RainOnTrees {
      
          public static RainOnTrees newInstance() {
              return new RainOnTrees();
          }
      
      
          private RainOnTrees() {
              // Private constructor.
          }
      
          public void startRain() {
      
              // some code here
          }
      }
      

    By using this strategy, you'll be able to use Mockito and keep your class closed for extension with little boilerplate code.

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

    Just to follow up. Please add this line to your gradle file:

    testCompile group: 'org.mockito', name: 'mockito-inline', version: '2.8.9'
    

    I have tried various version of mockito-core and mockito-all. Neither of them work.

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

    Use Powermock. This link shows, how to do it: https://github.com/jayway/powermock/wiki/MockFinal

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

    I had the same problem. Since the class I was trying to mock was a simple class, I simply created an instance of it and returned that.

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