How can I use Groovy's mock.interceptor package to mock an objects constructor? - groovy

In my attempt to mock an object in Groovy using the mock.interceptor package:
def mock = new MockFor(TheClass);
mock.demand.theMethod{ "return" }
mock.use {
def underTest = new TheClass()
println underTest.theMethod()
}
The problem I have is when creating TheClass() in the use{ block, it uses the actual constructor which, in this circumstance, I'd rather it not use. How can I create an instance of this class so I can test the method I do care about, theMethod, without needing to use the constructor?
Using EasyMock/CE, mocks can be made without using the constructor, but am curious how to achieve that in Groovy.

I recently saw a presentation by the author of GMock and it has some hooks to allow "constructor" mocking which I think is what you are after.
e.g.
def mockFile = mock(File, constructor('/a/path/file.txt'))
This library differs from that "built in" to groovy, however it looked very well written, with some thought put into the kinds of things you want to mock and more importantly the error messages you would get when tests should fail.
I think this is what you are after. I would say use constructor mocking with care - it could be a smell that you should inject a Factory object, but for some things it looked to work well.

You can use the interceptConstruction flag when calling MockFor, see
MockFor.

Related

Is there an alternative to RETURNS_DEEP_STUBS for mocking chained methods with Mockito?

I have a db service save() method which allows method chaining:
#Service
public class Service {
...
public Service save(...) {
...
return this;
}
and this works just great as:
service.save(this).save(that).save(other);
When I come to mock it with Mockito though it breaks unless I use
Service serviceMock = mock(Service.class, RETURNS_DEEP_STUBS);
IIUC though, the use of RETURNS_DEEP_STUBS is considered bad. Is there a better way to mock a class with method call chaining?
Your pattern for save is very similar to a Builder pattern, which makes the question similar to "How to mock a builder with mockito" elsewhere on SO.
Per David Wallace's answer there, you can write an Answer that detects whether the mock is an instance of the return type of the method, and return the mock in only that case. This functionality was also built into the Mockito library as RETURNS_SELF in Mockito 2.0. As with any Answer, you can use this on any specific method call with thenAnswer or as the second parameter of mock to make it the default answer, but bear in mind the Mockito documentation warning that methods with generous return types (e.g. Object) will return the mock whether or not that was intended.

How to mock an array of interfaces using powermock or mockito

I am mocking an interface array which throws java.lang.IllegalArgumentException: Cannot subclass final class class.
Following are the changes I did.
Added the following annotations at class level in this exact order:
#Runwith(PowerMockRunner.class)
#PrepareForTest({ Array1[].class, Array2[].class })
Inside the class I am doing like this:
Array1[] test1= PowerMockito.mock(Array1[].class);
Array2[] test2= PowerMockito.mock(Array2[].class);
and inside test method:
Mockito.when(staticclass.somemethod()).thenReturn(test1);
Mockito.when(staticclass.somediffmethod()).thenReturn(test2);
Basically I need to mock an array of interfaces.
Any help would be appreciated.
Opening up another perspective on your problem: I think you are getting unit tests wrong.
You only use mocking frameworks in order to control the behavior of individual objects that you provide to your code under test. But there is no sense in mocking an array of something.
When your "class under test" needs to deal with some array, list, map, whatever, then you provide an array, a list, or a map to it - you just make sure that the elements within that array/collection ... are as you need them. Maybe the array is empty for one test, maybe it contains a null for another test, and maybe it contains a mocked object for a third test.
Meaning - you don't do:
SomeInterface[] test1 = PowerMock.mock() ...
Instead you do:
SomeInterface[] test1 = new SomeInterface[] { PowerMock.mock(SomeInterface.class) };
And allow for some notes:
At least in your code, it looks like you called your interface "Array1" and "Array2". That is highly misleading. Give interfaces names that say what their behavior is about. The fact that you later create arrays containing objects of that interface ... doesn't matter at all!
Unless you have good reasons - consider not using PowerMock. PowerMock relies on byte-code manipulation; and can simply cause a lot of problems. In most situations, people wrote untestable code; and then they turn to PowerMock to somehow test that. But the correct answer is to rework that broken design, and to use a mocking framework that comes without "power" in its name. You can watch those videos giving you lengthy explanations how to write testable code!

writing unit test using mockito

I am writing unit tests in java using mockito.
This is the statement that I am trying to test.
final Map<EntityKey, Element<Movie>> resultMap = Watcher.watch(movies);
movies is Set of movie names which is a key to identify a movie.
I mocked watcher class
final Watcher<Movie> watcher = mock(Watcher.class);
Mockito.when(watcher.watch(Matchers.any(Set.class))).thenReturn()
what to include in "thenReturn"??
In the thenReturn function you need to pass an object of the same type as the method you are mocking's return type.
When this method is then called on that object, it will return the object you passed to thenReturn instead of actually going into the function.
This is the core concept behind mocking.
Having said that. If you are trying to test the Watcher.watch method then you probably don't want to mock it anyway. You should only mock those classes you are NOT testing.
You would need to make a Map<EntityKey,Element<Movie>> that would be suitable for use in the rest of the test. I'm not quite sure what your test is actually trying to assert, but whatever it is, choose the Map accordingly. Your Map object is what you want to return from thenReturn.

Is there a Mockito equivalent way to expect constructor invocations like PowerMock.expectNew?

If it doesn't, does it exist on EasyMock?
Thanks.
PowerMock is intended as an extension of both EasyMock and Mockito. From the horse's mouth: "PowerMock is a framework that extend other mock libraries such as EasyMock with more powerful capabilities."
In any case, there is no EasyMock equivalent to expectNew and neither is there one in Mockito, either - that's exactly the hole that PowerMock is trying to fill. That being said, PowerMock is perfectly capable of doing this with Mockito. Here is the sample from the documentation:
How to mock construction of new objects
Use PowerMockito.whenNew, e.g.
whenNew(MyClass.class).withNoArguments().thenThrow(new
IOException("error message"));
Note that you must prepare the class
creating the new instance of MyClass for test, not the MyClass itself.
E.g. if the class doing new MyClass() is called X then you'd have to
do #PrepareForTest(X.class) in order for whenNew to work.
How to verify construction of new objects
Use PowerMockito.verifyNew,
e.g.
verifyNew(MyClass.class).withNoArguments();

cast closure map to object with a private constructor in groovy

I am using groovy to create some mock classes for a test case. I am basically creating dummy objects where all the methods return null so that i can run my testcase.
I am using the following syntax:
MessageFactory.instance = ["getMessage": {a,b,c,d -> "dummy"}] as MessageFactory
So here i am trying to overwrite the singleton instance with my on fake factory object. The problem is that MessageFactory's constructor happens to be a private method. This gives me an illigal access exception when i run the code above. Is there a away i can create a proxy in groovy and overcome the private constructor issue?
If you have access to the MessageFactory, and are willing to modify it, then you use the standard dependency-injection solution, as detailed here: mock singleton
..Though it's not particularly Groovy.
Otherwise, the best workaround I've found is to override the method(s) on the singleton instance itself, like so:
#Singleton
class Test{
def method(){"Unmocked method called"}
}
def test = Test.instance
test.metaClass.method = {-> null}
test.method() // Now returns null
Naturally, as a singleton, this instance doesn't change (at least in theory)... So, overriding methods in this manner is effectively global.
Edit: Or you can use GMock, which supports constructor mocking (among other things).

Resources