Open GoogleCodeExporter opened 9 years ago
Original comment by brice.du...@gmail.com
on 11 Feb 2011 at 10:24
Yeah, interesting idea. We'll look at it.
Cheers!
Original comment by szcze...@gmail.com
on 15 Feb 2011 at 10:00
I think mocking abstract classes is a great idea and it's a one-for-all
solution to many problems such as providing partial mocks for fat interfaces,
and for mocking async style API. For example:
abstract MockCreditCardService implements CreditCardService {
@Override public void getCreditCard(String id, Callback<CreditCard> callback) {
callback.onSuccess(getCreditCard(id));
}
// traditional non-callback variant for easy mocking
abstract CreditCard getCreditCard(String id);
}
@Partial @Mock MockCreditCardService service;
when(service.getCreditCard("id1")).thenReturn(creditCard);
But I think Answer itself only gets half of the job done.
When users get to create abstract classes, they will want to use fields:
abstract class MockFoo {
private final Bar bar = new Bar();
...
}
It'd be surprising if this bar field isn't initialized because Mockito doesn't
call the constructor.
In fact, in our internal EasyMock-based testing infrastructure, we find the
partial-mock for abstract class quite useful.
Another useful feature I'd hate to miss (we are internally discussing to move
to Mockito because it's damn cool!), is the ability to create non-static inner
classes. With inner class, the mock gets to access all the other mocks created
by the test. For a class with non-default constructor, it may be the only type
safe way for the test to pass in mocks. For example:
@Mock Request request;
abstract class MockPresenter extends Presenter {
MockPresenter() {
super(request);
}
...
}
So, in general, I hope Mockito can support partial-mock-abstract-class in the
core, with the default constructor called (and optionally suppressed).
Original comment by yuj...@gmail.com
on 19 Apr 2011 at 1:53
And this may be directly related to issue 114.
Regarding implementation, I haven't digged Mockito code enough. But EasyMock
uses cglib Enhancer. It's not hard to pick a constructor when generating class
with Enhancer. I suppose Mockito could do the same thing?
Original comment by yuj...@gmail.com
on 19 Apr 2011 at 1:56
It should be fairly easy. Objenesis creates instances and it configirable
creation strategies.
Original comment by szcze...@gmail.com
on 19 Apr 2011 at 6:55
Here's a suggested API: we can have a @PartialMock annotation, or @Partial
@Mock, when initMocks(this) is called, it scans the partial mocked fields and
initialize them by invoking the parameterless constructor of the abstract class.
@PartialMock private MockCreditCardService creditCardService;
abstract class MockCreditCardService implements CreditCardService {
private final Map<String, Callback<CreditCard>> callbacks = new HashMap<>();
@Override public void getCreditCard(String id, Callback<CreditCard> callback) {
calls.put(id, callback);
}
}
Partial mocks should be able to handle non-static inner classes by injecting
the enclosing test instance as the hidden outer "this" parameter. It allows the
partials to use other mocked collaborators.
I hacked up an implementation using default answer but it would be nice if it's
built into Mockito core (and if the idea sounds reasonable, I'll volunteer to
send a patch)
Original comment by yuj...@gmail.com
on 18 Dec 2012 at 5:22
Original issue reported on code.google.com by
bo.majew...@gmail.com
on 27 Jan 2011 at 6:33