Making use of ReflectionTestUtils to mock a static class - java

I am writing unit test for a class which makes use of the static class ProcessTimer. To be precise, ProcessTimer.startTimer().
I am looking for a way to mock this call. I have used plain ReflectionUtils and PowerMock before, but I am wondering if I could do this with ReflectionTestUtils which comes from Spring.
If possible, I could remove the PowerMock dependencies and rewrite few other tests too. Any help is greatly appreciated!

ReflectionTestUtils is not for mocking. Rather, it is only for setting/reading non-public fields and invoking non-public methods.
If you want to mock what is returned by a static method you will have to use a dedicated mocking framework for that -- for example, something like PowerMock as you mentioned.
Regards,
Sam (author of ReflectionTestUtils)

Related

Mock a static field in a Spring JUnit test

I am currently working on a Spring boot project. I'm writing a JUnit 5 test for a class which is as follows,
class TheClassUnderTest {
public String methodToTest() {
Map<Integer, Object> collection = SomeOtherClass.someStaticField;
/*
Some processing logic
*/
}
}
I want to know if there is a way to mock the usage of "SomeOtherClass.someStaticField" so that I can test my class "TheClassUnderTest". I also use Mockito, so any answers using Mockito are also welcome
Mockito added support for static methods moving since Mockito 3.4.0, and before that you could use powerMockito to achieve this.
Having said that, what you are asking. Mocking static field is not suuportrd by mockito and actually Mockito does not support mocking class fields at all, only methods.
I would suggest wrapping the static variable in some method, and preferably make it non static.
Generally avoid static methods, as a class depending on static method of another class is strongly coupled with it and is bad practice for TDD.

How to prevent mocking of a class in mockito 3.x?

In mockito 1 we could have made a class final with static methods to not prevent mocking. Now as mentioned in mockito doc mockito-inline allows mocking of final and static methods.
Can someone let me know if there is a way to prevent mocking of a class in mockito 3.x?
It's turned off by default:
"This mock maker is turned off by default because it is based on completely different mocking mechanism that requires more feedback from the community. It can be activated explicitly by the mockito extension mechanism, just create in the classpath a file /mockito-extensions/org.mockito.plugins.MockMaker containing the value mock-maker-inline."
According to: https://javadoc.io/static/org.mockito/mockito-core/3.7.7/org/mockito/Mockito.html#39

Is there a an equivalent doCallRealMethod for spies (aka doCallMockMethod)?

I need to mock out a class due to one third party required dependency, so I can unit test it (I cannot remove this dependency).
So what I've done is mocked out the class and then utilized Mockito.doRealMethod() for all the function calls, but I feel this sort of abstracts what is being really done.
When in reality I want the real class and just want to mock out that one call.
Partial mocking of a class is supported via spy in Mockito. See the Mockito documentation on partial mocks for more information.
Another possibility may be to use org.mockito.Mockito.CALLS_REAL_METHODS, such as:
YourClass YOUR_MOCK = Mockito.mock( YourClass.class, CALLS_REAL_METHODS );
You can override the real method on a spy like
Mockito.doReturn("foobar").when(mySpy).myMethod();

Mockito and final equals() method in class - is it mockable?

I want to mock a class from other library using Mockito. I read that Mockito relies on specific (CGLIB provided I think) implementation of equals method. Unfortunately this outer class has equals() denoted with final modifier, and there is throwing exception in its body.
When I try to mock this class I always get exception from this method. CGLIB apparently doesn't get by with final, and real method is called.
Any ideas? What can I do, to mock this class using Mockito? Maybe other library will handle it?
[EDIT] quick explanation: I don't want to mock equals(), I check other methods. Problem is that mockito internally uses equals(), I don't know what for. As equals() is final, real method is called with exception throwing. I had hope that there is some setting in mockito "don't use equals()" :-)
Thanks for answers, I will read them closely tomorrow.
This matrix shows features supported by different frameworks:
External link to the matrix here.
According to this, only PowerMock and JMockit can mock final methods.
Mockito cannot mock final methods. Apparently PowerMock can though.
A hacky workaround could be to create a non-final method that delegates to the final equals method and mock that.
I believe that the steps to mock a final method with PowerMock and Mockito API would be: run your tests with the #RunWith(PowerMockRunner.class) then prepare the class you want to mock #PrepareForTest(ClassToBeMocked.class). After that, mock your object and use the when method to mock the equals method.
I think that it won't work if you do not use the PrepareForTest annotation in your test class.

Mocking Static Methods

As i did some research i have found out that PowerMock is able to mock static java methods.
Can someone explain (technically) what is PowerMock doing different than JUnit and others which can not or do not? And also why static methods are(were) causing issues when they are tried to mock?
thanks
http://blog.jayway.com/2009/05/17/mocking-static-methods-in-java-system-classes/
In order to mock an instance method, you can simply override it in a subclass. You can't do that with static methods because there's no "static polymorphism".
Powermock can do it because it works with bytecode, while other popular frameworks rely on polymorphism and create subclasses with CGLIB.
From the link: "Basically all standard mock frameworks use CGLib to create a mock object which means that they're based on a hierarchical model (CGLib creates a sub class of the class to test at run-time which is the actual mock object) instead of a delegation model which PowerMock uses through it's byte-code manipulation by delegating to the MockGateway."

Categories