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

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

Related

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();

Making use of ReflectionTestUtils to mock a static class

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)

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."

Java Unit tests on methods that use third parties libs that don't use Interfaces

I'd like to know how do you test your methods if the libs you are using don't use Interfaces
My class is like
private ThirdParyClass thirdPartyClass;
void myMethod() {
AnotherThirdPartyClass param = "abc";
...
thirdPartyClass.execute(param);
}
I want to test that execute is called with the "abc" param.
I was thinking in creating MyInterface with an implementation that wraps the ThirdPartyClass and then change the class attribute to refer MyInterface. Quite boring stuff but I don't see any other way to be able to successfully test my class.
If ThirdParyClass was an Interface I could mock it, but in this case how do you procede?
i do not know which mock implementation you use it. But EasyMock has an extension available at the EasyMock home page that generate mock Objects for classes. See your mock implementation whether it does not support mock Objects for classes.
regards,
You can use JMockit. It goes far beyond what is possible with EasyMock Class Extension or with jMock and its ClassImposteriser. You actually get all the power of AspectJ, but with a much easier to use, mocking-specific, API.
As long as the third party class you're using isn't final and you don't need to mock final methods you can use JMock and the ClassImposteriser to mock it and carry on as normal.
private Mockery context = new Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
AnotherThirdPartyClass mockThirdParty = context.mock(AnotherThirdPartyClass.class);
Note you'll need to add some additional dependencies (jmock-legacy-2.5.1.jar, cglib-nodep-2.1_3.jar and objenesis-1.0.jar)
Why not just use AspectJ (AOP) for the unit testing.
By using an around aspect you can then control what gets passed into the method and better monitor it.
If you need to have it extend an interface, you can modify the class through aspects to give it more functionality, such as turning logging on/off or getting performance information.
Then, when you are done, you remove the aspects before putting this into production by just not including the aspect class files in the build.

Categories