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

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

Related

Mockito equivalent of EasyMock's MockBuilder

EasyMock has a function called createMockBuilder with which someone can specify a partially mocked class.
Is it possible to do the same with Mockito?
For example in EasyMock some can do the following :
classA mockedA = EasyMock.
createMockBuilder(A.class).
withConstructor(B.class,C.class).
withArgs(b,null).
addMockedMethod("print").
createMock();
Is it possible to do the same with Mockito?
Mockito does it a little differently from EasyMock. For instance, whereas in EasyMock, you decide which member functions you want mocked:
EasyMock.createMockBuilder(A.class).addMockedMethod("foo");
in Mockito, all member functions are mocked by default, and you can specify when you want to call an underlying function:
A a = Mockito.mock(A.class);
Mockito.when(a.foo()).thenCallRealMethod();
If you're wanting to mock only a few member functions with Mockito, I can think of two ways to proceed: The example above, and spying.
A a = Mockito.spy(A.class);
Mockito.when(a.foo()).thenReturn("ret");
a.bar(); // Calls the real A.bar() function.
Using a spy, member functions are not mocked by default, but can be mocked selectively. See more information here: http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#spy

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 class with annotated methods

I have concrete class that I want to mock. There are several annotated methods with annotations. I want to create class mock but I need to preserve that annotations.
I tried easymock. It subclasses my class without problems, but does not preserve annotations.
I would like to preserve annotations in easymock. If that is impossible are there any other mocking solution?
I prefer mockito which uses a different paradigm for mocking out classes. You don't have to subclass everything like you do with easymock.
http://code.google.com/p/mockito/
The javadoc itself has a ton of information about how to utilize the library
http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#2
Her is a short example from their documentation.
//You can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
//stubbing
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());
//following prints "first"
System.out.println(mockedList.get(0));
//following throws runtime exception
System.out.println(mockedList.get(1));
//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
//Although it is possible to verify a stubbed invocation,
//usually it's just redundant
//If your code cares what get(0) returns then something else
//breaks (often before even verify() gets executed).
//If your code doesn't care what get(0) returns then it should
not be stubbed. Not convinced? See here.
verify(mockedList).get(0);
So with this library you setup your tests and stub out the methods that you are interested in testing.
Hope you found this useful.

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