Mockito is used to mock the objects for unit testing. Same can be done using java reflection API. Does this mean Mockito is implemented on reflection API of java ?
No, Mockito doesn't use java.lang.reflect.Proxy, which only works on interfaces. (Even if it did, I'd be wary of logic that says "A can be used for B, that means library L used A for B".)
To allow for more flexible mocking, including mocking of concrete classes, Mockito generates bytecode for its mocks using:
CGLib/ASM/Objenesis for Mockito prior to 2.0 [source]
ByteBuddy for Mockito from 2.0 onwards
DexMaker to create .dex files for Android Dalvik VMs (since 1.9.5)
arbitrary implementations of MockMaker to support other platforms and packages (since 1.9.5)
For what it's worth, the CGLib Proxy class that Mockito used was designed to be a drop-in replacement for java.lang.reflect.Proxy.
Side note: Mockito definitely uses Java's reflection API, such as to refer to the Method object in InvocationOnMock.getMethod. This is probably not what you meant by "used to mock the objects", though.
Related
I've been trying to understand how Mockito mocking works. I've read various responses and there seems to be a conflicting argument whether Mockito uses reflection internally or not.
Here, it clearly says that mockito does not use Reflection:
https://stackoverflow.com/questions/15970810/using-mockito-to-mock-methods-by-reflection#:~:text=Mockito%20is%20a%20really%20well,easy%20to%20read%20and%20understand.
On the other hand, the most popular tutorial website says otherwise in the very first line under Mockito:
https://www.tutorialspoint.com/mockito/mockito_overview.htm
I'm slightly confused with what's true about mocking with Mockito.
Mockito uses the reflection internally. You can check it out this source code also on Mockito Git Library.
As per my understanding, these annotations used for methods with an access modifier that allows method invocation from another class for unit testing
#VisibleForTesting - com.google.common.annotations.VisibleForTesting
#TestOnly - org.jetbrains.annotations.TestOnly
The first big difference is obviously that it's provided by different projects.
#VisibleForTesting is part of the Google Guava libraries and #TestOnly is part of JetBrains annotations which are associated with JetBrains, the makers of IntelliJ IDEA, among others.
Comparing the JavaDoc of the two shows that they serve basically identical goals: #TestOnly and #VisibleForTesting.
Note that the documentation of both annotations contain a note effectively warning you that the annotation itself does not prevent production code from calling the annotated method. JetBrains suggests the use of static checking tools that support that annotation (one of which is presumably built into IntelliJ IDEA) and Guava suggests the use of external checker tools with an explicit list of forbidden APIs.
tl;dr They indicate effectively the same thing. The decision which one to use depends mostly on which tools you are using to act on them and which one they support. Already using other annotations or classes from one of those packages is another reason to pick one over the other.
They are not for the same thing.
#VisibleForTesting is used for a methods that could be private/package-visible but has a higher visibility so it can be used by tests. Such a method can still be called in Production.
#TestOnly is used for a method that can only be used by tests, for instance to create a stub or to perform an additional validation only when testing. Such a method should never be called in Production, although the annotation won't prevent that.
By the way, JetBrains provide both annotations, so they can be used in the same project.
I'm trying to use PowerMock as a library in another application. Is there a way to use it to mock a static method call without using annotations (I'm in Clojure which doesn't really do annotations)
According to powermock support and this blog, I guess there is no way to avoid annotations in test. I guess we need the #PrepareForTest(StaticClass.class) however. So I believe it is not possible to avoid #PrepareForTest atleast. May be I am wrong, but just thought of sharing what I found.
In fact, it's possible, although the way to final solution is painful.
PowerMock runner just initializes test environment in different classloader, in which the classes specified in PrepareForTest annotation are tweaked by Javassist. So assumed you mimic the work of the classloader and call Javassist by yourself, you can achieve the same effect.
As an example, I utilized PowerMock (internals without annotations) to discover name of method for given method reference. Further info can be found on my blog (in Czech, with working examples). I emphasize such an usage is only experimental and not suitable for production usage.
Are there any libraries for the JVM that allow mocking of static methods WITHOUT needing annotations? I am attempting to build this feature into a Clojure testing framework (Midje). Clojure has very poor, or non-existant annotation support.
Use powermock.It's a great library for mocking. And here is an example that explains how to mock static methods.
Would anyone suggest a Mock library and provide the reasoning behind the pick?
I am looking to introduce one to the existing code base.
Thanks.
This is the best comparison I've seen, of multiple Java mocking frameworks, including EasyMock and mockito. [The original page is offline; this link is to an archived copy.]
It includes EasyMock, Mockito, jMock, SevenMock, JMockit, rMock, Unitils.
I used EasyMock first, but have moved to Mockito. Unit tests created with EasyMock were sometimes fragile and hard to debug. Mockito is easy, partly because it distinguishes between stubbing and verification. Here's a Mockito-oriented comparison of it and EasyMock: http://code.google.com/p/mockito/wiki/MockitoVSEasyMock.
My suggestion is JMockit (I wrote it). The project site has a lot of information (and hundreds of actual JUnit tests) comparing several Java mocking APIs (EasyMock, jMock, JMockit, Mockito, PowerMock, Unitils Mock), as well as an extensive feature comparison matrix.
easymock. Reasons, from their site
'EasyMock provides Mock Objects for interfaces (and objects through the class extension) by generating them on the fly using Java's proxy mechanism. Due to EasyMock's unique style of recording expectations, most refactorings will not affect the Mock Objects. So EasyMock is a perfect fit for Test-Driven Development.'
Here is another comparison: http://softwareinabottle.wordpress.com/2010/09/12/finding-the-mock-framework-that-best-suits-me-part-1-the-contenders/
http://softwareinabottle.wordpress.com/2010/10/06/comparing-java-mock-frameworks-part-2-creating-mock-objects/