How to mock static methods java
How to mock static methods java
How to mock static methods with Mockito
1. Introduction
This article will be covering mocking static methods with Mockito. We will try to answer the question is this even possible to do it and why should we ever mock anything that is static.
2. Static methods
Let’s start with a simple definition. Static methods are that methods in Java that can be called without creating an instance of the class. A static method belongs to the class rather than the object of a class.
Using static methods in Java is sometimes necessary, however, most developers limit their use to pure functions which are independent (not using external dependencies). Whether we like them or not, we do sometimes have to rely on them and also mock them in unit tests.
3. Mocking static method with Mockito 3.x
The good news is that from the latest Mockito version mocking static methods is finally supported.
To make this possible, a single dependency had to be added to the pom.xml file:
The latest version of Mockito inline dependency should be found in our Maven Repository.
If you are using mockito-core you will need to replace it with mockito-inline dependency otherwise you will face the following exception:
3.1. Simple class with a static method use for testing
Let’s consider we have a simple class WelcomeUtil with a single static method generateWelcome(. ) that we want to mock in the JUnit test:
3.2. Mockito test class
The test code of this class could looks as follows:
There are some things we need to explain here:
4. Mocking static method with Mockito in older versions 2.x
Now, what about the older version of the Mockito framework? does it support mocking static methods?. The answer is unfortunately NO.
But we could use another library such as PowerMock to mock the static method without using the latest version of Mockito.
First, let’s start with adding necessary dependencies to our pom.xml file:
The list of dependencies we used (you can check the latest versions in links below):
4.1. PowerMock test class
The PowerMock uses internally Mockito API so we still need the Mockito library in our dependencies.
The following shows how to create a test that mocks the static WelcomeUtil.generateWelcome(. ) method just like in the above example:
In this example mockStatic(. ) and when(. ) methods comes from PowerMockito library.
5. Mocking static method with Mockito 4.x
6. Conclusion
In this article, we presented how to mock static methods with Mockito and PowerMockito libraries. When it is not about mocking methods from third-party libraries, consider refactoring the code so that mocking a static method wouldn’t be necessary. It is always not the best solution.
Test examples used in this article, are available in the GitHub Repository:
How to mock static method without powermock
Is there any way we can mock the static util method while testing in JUnit?
I know Powermock can mock static calls, but I don’t want to use Powermock.
Are there any alternatives?
4 Answers 4
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
(I assume you can use Mockito though) Nothing dedicated comes to my mind but I tend to use the following strategy when it comes to situations like that:
1) In the class under test, replace the static direct call with a call to a package level method that wraps the static call itself:
2) Spy the class under test while testing and mock the wrapped package level method:
Here is an article I wrote on spying that includes similar case, if you need more insight: sourceartists.com/mockito-spying
When you have static code that gives you trouble in your unit tests; so that you feel you have to «mock it away», you have exactly these options:
In other words: if you want to use a mocking framework, you have to use one of those listed above. On the one side, that is absolutely fair. static is one part of the Java language; so why not use a framework that allows you to deal with it?
But of course: you still have the static call in your production code then. Leading to tight coupling, and preventing polymorphism.
How can I easily mock out a static method in Java (jUnit4)
How do I easily mock out a static method in Java?
I’m using Spring 2.5 and JUnit 4.4
I don’t control the static method that my service needs to invoke so I cannot refactor it to be more unit-testable. I’ve used the Log4J Logger as an example, but the real static method is similar. It is not an option to change the static method.
Doing Grails work, I’m used to using something like:
How do I do something similar in Java?
8 Answers 8
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
Do you mean you can’t control the calling code? Because if you control the calls to the static method but not the implementation itself, you can easily make that testable. Create a dependency interface with a single method with the same signature as the static method. Your production implementation will just call through to the static method, but anything which currently calls the static method will call via the interface instead.
You can then mock out that interface in the normal way.
The JMockit framework promises to allow mocking of static methods.
In fact, it makes some fairly bold claims, including that static methods are a perfectly valid design choice and their use should not be restricted because of the inadequacy of testing frameworks.
Regardless of whether or not such claims are justifiable, the JMockit framework itself is pretty interesting, although I’ve yet to try it myself.
Mocking static methods with Mockito
I’ve written a factory to produce java.sql.Connection objects:
18 Answers 18
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
Use PowerMockito on top of Mockito.
Mocking of static methods in Mockito is possible since Mockito 3.4.0. For more details see:
In your case, something like this:
NOTE: mocking STATIC METHODS requires mockito-inline dependency instead of mockito-core.
For JUnit5 also add this:
The typical strategy for dodging static methods that you have no way of avoiding using, is by creating wrapped objects and using the wrapper objects instead.
The wrapper objects become facades to the real static classes, and you do not test those.
A wrapper object could be something like
Finally, your class under test can use this singleton object by, for example, having a default constructor for real life use:
And here you have a class that can easily be tested, because you do not directly use a class with static methods.
If you are using CDI and can make use of the @Inject annotation then it is even easier. Just make your Wrapper bean @ApplicationScoped, get that thing injected as a collaborator (you do not even need messy constructors for testing), and go on with the mocking.
As mentioned before you can not mock static methods with mockito.
If changing your testing framework is not an option you can do the following:
Create an interface for DriverManager, mock this interface, inject it via some kind of dependency injection and verify on that mock.
For those who use JUnit 5, Powermock is not an option. You’ll require the following dependencies to successfully mock a static method with just Mockito.
mockito-junit-jupiter add supports for JUnit 5.
And support for mocking static methods is provided by mockito-inline dependency.
The try-with-resource block is used to make the static mock remains temporary, so it’s mocked only within that scope.
When not using a try block, make sure to close the mock, once you are done with the assertions.
Mocking void methods:
Observation : When you call static method within a static entity, you need to change the class in @PrepareForTest.
For the above code if you need to mock MessageDigest class, use
While if you have something like below :
then, you’d need to prepare the class this code resides in.
And then mock the method :
Your example becomes:
You can do it with a little bit of refactoring:
Then you can extend your class MySQLDatabaseConnectionFactory to return a mocked connection, do assertions on the parameters, etc.
The extended class can reside within the test case, if it’s located in the same package (which I encourage you to do)
Mockito cannot capture static methods, but since Mockito 2.14.0 you can simulate it by creating invocation instances of static methods.
Example (extracted from their tests):
Their goal is not to directly support static mocking, but to improve its public APIs so that other libraries, like Powermockito, don’t have to rely on internal APIs or directly have to duplicate some Mockito code. (source)
Disclaimer: Mockito team thinks that the road to hell is paved with static methods. However, Mockito’s job is not to protect your code from static methods. If you don’t like your team doing static mocking, stop using Powermockito in your organization. Mockito needs to evolve as a toolkit with an opinionated vision on how Java tests should be written (e.g. don’t mock statics. ). However, Mockito is not dogmatic. We don’t want to block unrecommended use cases like static mocking. It’s just not our job.
To mock static method you should use a Powermock look at: https://github.com/powermock/powermock/wiki/MockStatic. Mockito doesn’t provide this functionality.
I found one solution in Mockito. This feature comes with a version only from 3.4.0
In your build.gradle replace mockito-core:3.3.3 by mockito-inline:3.4.0:
what are we going to mock
Mock the static method
I think this could help us.
Since that method is static, it already has everything you need to use it, so it defeats the purpose of mocking. Mocking the static methods is considered to be a bad practice.
If you try to do that, it means there is something wrong with the way you want to perform testing.
Of course you can use PowerMockito or any other framework capable of doing that, but try to rethink your approach.
For example: try to mock/provide the objects, which that static method consumes instead.
When you try to mock the static method, you have to write the test inside the try block. because It’s important to note that scoped mocks must be closed by the entity that activates the mock.
In the above example, we have to mock the Tester Class testStatic Method with input param as «Testing. «. Here, this method will return a ReturnObject class type object. Hence we write mockito when chain like above.
Don’t forget to add below dependency in your Gradle/maven
Use JMockit framework. It worked for me. You don’t have to write statements for mocking DBConenction.getConnection() method. Just the below code is enough.
@Mock below is mockit.Mock package
There is an easy solution by using java FunctionalInterface and then add that interface as dependency for the class you are trying to unit test.
For mocking static functions i was able to do it that way:
wrapper code snippet (not really functional, just for illustration)
of course having multiple such functions accumulated in a single wrapper class might be beneficial in terms of code reuse.
Here I share my mockito MockStatic solution based on an extension as promised in my answer to leokom’s solution.
So, why does Mockito choose try-with-resources? Well, simply because they want to keep a tidy ship. That is good programming after all. Try-with-resources allows construction with guaranteed calling of the close method. But in JUnit we already have that in BeforeEach and AfterEach. And one can easily add these for a generic purpose to each test class using an Extension that implements BeforeEachCallback and AfterEachCallback.
So much for the theory. Let’s make a static mock for
I started with an annotation to be able to mark the fields in my test class that I want to use as static mocks.
This allows me to create a field in my test class for static mocking that I can easily find in my Extension class.
I added the Extension I created to my test class. You have two options.
I used the latter of the two.
Now we need something to be returned for the static when it’s called:
The whole test class:
Now let’s take a look at the Extension class.
The nice thing about this extension is that you can add additional mocking stuff. I added verification of no more interactions on all mocks in the AfterEach. This is now automatic when we use this extension. I also added similar behavior for construction mocking as for the static mocking.
As you see, I made my own reflection helper class. I know there are some standard reflection helper classes and those might be better. Here is mine for this purpose.
Mocking Private, Static and Void Methods Using Mockito
Learn Mocking Private, Static and Void methods in Mockito with Examples:
In this series of hands-on Tutorials on Mockito, we had a look at the different types of Mockito Matchers in the last tutorial.
Generally speaking, mocking private and static methods come under the category of unusual mocking.
If the need arises to mock private and static methods/classes, it indicates poorly refactored code and is not really a testable code and is most likely that some legacy code which was not used to be very unit test friendly.
Having said that, there still exists support for Mocking private and static methods by few unit testing frameworks like PowerMockito (and not directly by Mockito).
Mocking “void” methods are common as there might be methods which are essentially not returning anything, like updating a database row (consider it as a PUT operation of a Rest API endpoint which accepts an input and does not return any output).
Mockito provides full support for mocking void methods, which we will see with examples in this article.
What You Will Learn:
Powermock – A Brief Introduction
For Mockito, there is no direct support to mock private and static methods. In order to test private methods, you will need to refactor the code to change the access to protected (or package) and you will have to avoid static/final methods.
Mockito, in my opinion intentionally does not provide support for these kinds of mocks, as using these kinds of code constructs are code smells and poorly designed code.
But, there are frameworks which support mocking for private and static methods.
Powermock extends capabilities of other frameworks like EasyMock and Mockito and provides the capability to mock static and private methods.
#1) How: Powermock does this with the help of custom bytecode manipulation in order to support mocking private & static methods, final classes, constructors and so on.
#2) Supported packages: Powermock provides 2 extension APIs – one for Mockito and one for easyMock. For the sake of this article, we are going to write examples with the Mockito extension for power mock.
#3) Syntax: Powermockito has an almost similar syntax as Mockito, except some additional methods for mocking static and private methods.
#4) Powermockito Setup
In order to include the Mockito library in gradle based projects, below are the libraries to be included:
Similar dependencies are available for maven as well.
Powermock-api-mockito2 – The library is required to include Mockito extensions for Powermockito.
Powermock-module-junit4 – Module is required to include PowerMockRunner (which is a custom runner to be used for running tests with PowerMockito).
An important point to note here is that PowerMock does not support Junit5 test runner. Hence the tests need to be written against Junit4 and the tests need to be executed with PowerMockRunner.
To use PowerMockRunner – the test class needs to be annotated with @RunWith(PowerMockRunner.class)
Now let’s discuss, mocking private, static and void methods in detail!
Mocking Private Methods
Mocking private methods, which are called internally from a method under test can be unavoidable at certain times. Using powermockito, this is possible and the verification is done using a new method named ‘verifyPrivate’
Let’s take an Example where method under test calls a private method (which returns a boolean). In order to stub this method to return true/false depending on the test, a stub needs to be set up on this class.
For this Example, the class under test is created as a spy instance with mocking on few interface invocations and private method invocation.
Important points to Mock Private Method:
#1) The test method or test class needs to be annotated with @PrepareForTest(ClassUnderTest). This annotation tells powerMockito to prepare certain classes for testing.
These will be mostly those classes that need to be Bytecode manipulated. Typically for final classes, classes containing private and/or static methods that are required to be mocked during testing.
Example:
#2) To setup stub on a private method.
Syntax – when(mock or spy instance, “privateMethodName”).thenReturn(//return value)
Example:
#3) To verify the stubbed private method.
Syntax – verifyPrivate(mockedInstance).invoke(“privateMethodName”)
Example:
Complete Test Sample: Continuing the same example from the previous articles, where priceCalculator has some mocked dependencies like itemService, userService etc.
We have created a new method called – calculatePriceWithPrivateMethod, which calls a private method inside the same class and returns whether the customer is anonymous or not.
Mocking Static Methods
Static methods can be mocked in a similar way as we saw for the private methods.
When a method under test, involves using a static method from the same class (or from a different class), we will need to include that class in prepareForTest annotation before the Test (or on the test class).
Important points to Mock Static Methods:
#1) The test method or test class needs to be annotated with @PrepareForTest(ClassUnderTest). Similar to mocking private methods/classes, this is required for static classes too.
#2) One extra step that is required for static methods is – mockStatic(//name of static class)
Example:
#3) To setup stub on a static method, is as good as stubbing any method on any other interface/class mock instances.
For Example: To stub getDiscountCategory() (which returns an enum DiscountCategory with values PREMIUM & GENERAL) static method of DiscountCategoryFinder class, simply stub as follows:
#4) To verify the mock setup on the final/static method, verifyStatic() method can be used.
Example:
Mocking Void Methods
Let’s first try to understand what kind of use cases might involve stubbing void methods:
#1) Method calls for example – that sends an email notification during the process.
For Example: Suppose you change your password for your internet banking account, once the change is successful you receive notification over your email.
This can be thought of as /changePassword as a POST call to Bank API which includes a void method call to send an email notification to the customer.
#2) Another common example of the void method call is updated requests to a DB which take some input and do not return anything.
Stubbing void methods (i.e. the methods that do not return anything, or else throw an exception), can be handled using doNothing(), doThrow() and doAnswer(), doCallRealMethod() functions. It requires the stub to be set up using the above methods as per the test expectations.
Also, please note that all the void method calls are by default mocked to doNothing(). Hence, even if an explicit mock setup is not done on VOID method calls, the default behavior is still to doNothing().
Let’s see Examples for all these functions:
For all the examples, let’s assume, that there are a class StudentScoreUpdates which has a method calculateSumAndStore(). This method calculates the sum of scores (as input) and calls a void method updateScores() on databaseImplementation instance.
We will be writing unit tests for the mock method call with the below examples:
#1) doNothing() – doNothing() is the default behavior for void method calls in Mockito i.e. even if you verify a call on void method (without explicitly setting up a void to doNothing(), the verification will still be successful)
Other usages along with doNothing()
a) When the void method is called multiple times, and you want to setup different responses for different invocations, like – doNothing() for the first invocation and throw an exception on the next invocation.
For Example: Set up mock like this:
b) When you want to capture the arguments that the void method was called with, the ArgumentCaptor functionality in Mockito should be used. This gives an added verification of arguments that the method was called with.
Example with ArgumentCaptor:
#2) doThrow() – This is useful when you simply want to throw an exception when the void method is invoked from the method under test.
For Example:
E.g. Modifying some value through the passed arguments, returning custom values/data which a normal stub could not have returned especially for void methods.
For the purpose of demonstration – I’ve stubbed the updateScores() void method to return an “answer()” and print the value of one of the arguments that should have been passed when the method should have been called.
Code Example:
#4) doCallRealMethod() – Partial mocks are similar to stubs (where you can call real methods for some of the methods and stub out the rest).
For void methods, mockito provides a special function called doCallRealMethod() which can be used when you are trying to set up the mock. What this will do, is call the real void method with the actual arguments.
For Example:
Tips & Tricks
#1) Including multiple static classes in the same test method/class – Using PowerMockito if there is a need to Mock multiple Static of Final classes then the class names in @PrepareForTest annotation can be mentioned as comma separated value as an array (it essentially accepts an array of the class names).
Example:
As shown in the example above, assume both PriceCalculator and DiscountCategoryFinder are final classes that need to be mocked. Both of these can be mentioned as an array of classes in PrepareForTest annotation and can be stubbed in the test method.
#2) PrepareForTest attribute Positioning – The positioning of this attribute is important with regards to the kind of tests that are included in the Test class.
If all the tests need to use the same final class, then it makes sense to mention this attribute at test class level which simply means that the prepared class will be available to all the Test Methods. As opposed to this, if the annotation is mentioned on the test method, then it will be available only to that particular tests
Conclusion
In this tutorial, we discussed various approaches to mock static, final and void methods.
Though using a lot of static or final methods hinders testability, and still, there is support available for testing/mocking to assist in creating unit tests in order to achieve greater confidence in the code/application even for legacy code which is generally not used to be designed for testability.
For static and final methods, Mockito does not have an out of box support, but libraries like PowerMockito (which heavily inherit a lot of things from Mockito) does provide such support and has to actually perform bytecode manipulation in order to support these features.
Mockito out of the box supports stubbing void methods and provides various methods like doNothing, doAnswer, doThrow, doCallRealMethod etc. and can be used as per the requirement of the test.
Most Frequently asked Mockito Interview Questions are briefed in our next tutorial.
Источники информации:
- http://stackoverflow.com/questions/44967108/how-to-mock-static-method-without-powermock
- http://stackoverflow.com/questions/1203027/how-can-i-easily-mock-out-a-static-method-in-java-junit4
- http://stackoverflow.com/questions/21105403/mocking-static-methods-with-mockito
- http://www.softwaretestinghelp.com/mock-private-static-void-methods-mockito/