Closed GoogleCodeExporter closed 9 years ago
I would like to add that it should not just be multiple interfaces, but a class
and
one or more interfaces.
Original comment by karlgsch...@gmail.com
on 28 Jan 2009 at 2:08
Issue 59 has been merged into this issue.
Original comment by szcze...@gmail.com
on 18 Feb 2009 at 10:02
[deleted comment]
See discussion thread, which describes the problem.
http://groups.google.com/group/mockito/browse_thread/thread/60ce44174c7dd3fe/87d
ab35b19c1ee16
Original comment by iczechowski@gmail.com
on 15 Apr 2009 at 1:21
If someone follows this issue then we need to know how really it is useful? We'd
prefer to keep Mockito API slim (please, not another overloaded mock() method!).
We're waiting for code samples with legitimate case for this feature.
Original comment by szcze...@gmail.com
on 21 Apr 2009 at 10:23
I think this is useful. We had a usecase (also Webservices - JAXB in our case -
if I
remember correctly) and could not write a test with mockito for it.
Is it really required to overload the mock() method? A vararg should do the
trick to
keep the api as is and also support multiple interfaces I think.
Original comment by knista.peter
on 22 Apr 2009 at 6:21
The problem among other things is related to generics. Consider the following
methods:
public <T extends Point & Colored> T getColoredPoint();
or
public <T extends Component & Highlightable> void doHighlight(T instance);
Some might argue that you shouldn't create methods like that, but I will
heartily
disagree. Such method signatures add clarity and safety. Since the generics
parameters can be bound by one class or interface and any number of additional
interfaces, it is necessary that Mockito be able to provide the ability to mock
the
same constraints.
Currently, to mock any output or input for those methods, I am required to
create
some class that extends/implements all of the pieces of the puzzle and mock it.
My
code is now littered with Mock objects. It is no longer clean and
straightforward.
The reason I moved to Mockito was to rid myself of these types of objects.
Original comment by karlgsch...@gmail.com
on 22 Apr 2009 at 12:20
>Currently, to mock any output or input for those methods, I am required to
create
>some class that extends/implements all of the pieces of the puzzle and mock it.
I don't play against those methods but they seem not to be good candidates to
mock
their output/input. Wouldn't you prefer to use real objects for those?
It seems that the case for multi-interface mocks is to mock method parameters /
method returnables. Those objects are (following Misko Hevery's nomenclature
because
I like it ;) *newables* and it's best to use real implementations of those. I'm
just
hoping Mockito is not becoming a library for making it easy to create instances
of
objects that are difficult to create. Because for this problem there are
completely
different resolutions & patterns. Tell us your thoughts - does it makes sense
what
I'm saying?
Original comment by szcze...@gmail.com
on 22 Apr 2009 at 8:14
I guess I don't understand how using the "newable" makes it easy to validate
calls
on the object. The point, for me, of using the mock is not in creating
"difficult"
objects, but in ensuring that specific things occur to the mocked object.
Original comment by karlgsch...@gmail.com
on 23 Apr 2009 at 12:53
Ok, could you post an example with some code that you had to manually implement
an
adapter where you preferred to use Mockito?
Original comment by szcze...@gmail.com
on 23 Apr 2009 at 9:38
Actually, I can't, which is unfortunate. The code is question is considered
proprietary and I can't release it or the tests. I can take a stab at
describing
the problem more fully. So here goes:
I have a set of objects that I need to design that have commonalities, but the
commonalities are a mix-and-match. To tackle this problem, I created a series
of "aspect" interfaces. So, class A implements I and J, while B implements J
and K,
and C implements I, K and L, etc. As you can see there is no clear hierarchy
between these objects. True AOD might be the right answer, but that's not
going to
happen (politics). So the best I can do is these "aspect"-styled interfaces.
What
I need to test is that the various combinations are handled correctly. I could
pass
in mocks of the classes, but I don't know them at that point in the
development, so
I am currently forces to mock an abstract class that implements the
combinations.
I hope that's a bit more clear. Thanks for your patience.
Original comment by karlgsch...@gmail.com
on 23 Apr 2009 at 12:37
When I have had to mock a class which implements multiple interfaces I would
declare
something like this among the class fields, or just above the test method:
interface Tiger extends Running, Biting {}
I could then mock it as if it were a class implementing both. The same could be
done
for a class implementing many interfaces, as well as to mock a concrete class
implementing many interfaces e.g.:
abstract class Tiger extends Cat implements Running, Biting {}
I believe this gives all the freedom you want without any overhead, if anything
it
would be more readable than a varargs mock call. And if you added interfaces to
the
class you want to mock, you'd have to visit the test to change it anyway, so
there no
advantage there.
The only downside I can see would be if the base class didn't have a default
constructor then you would have to provide one to match, but it should only add
a
little noise... but it's still a disadvantage.
Don't see any great advantage in adding the capability to Mockito... unless
there's
use cases I haven't come across, or disadvantages I don't see...?
Regards,
Graham
Original comment by Grundlefleck@gmail.com
on 23 Apr 2009 at 7:58
I consider your Tiger examples ugly and noisy, but I respect your preference.
I do
something similar now; I just don't like it. ;)
As I see it, mock(A, B, C, ...) is very clear on what I am creating and
testing. It
happens at the time I request the mock and when I view declarations it's
exactly
where I need it to be. Having to find a Tiger hidden in the woods to determine
exactly what it looks like adds more indirection to the test than I like.
I also believe that the assumption you have of adding an interface means
changing
tests is also incorrect. The current method imlpementations shouldn't change
(without my knowledge and permission) when I add an interface and if I need to
change the tests to cope with the additional interface they are probably
testing at
the wrong level.
Karl
Original comment by karlgsch...@gmail.com
on 23 Apr 2009 at 8:11
One more thing: I think this is going to come down to where the user believes
the
noise is. Graham, for instance (and I hope I'm not misquoting), believes it
would
be noisy to have a mock(...). I believe the noise is involved in creating
dummy
classes to mock(Dummy).
I appreciate the time and consideration of this point. There is nothing more
that I
enjoy than a good archetectural debate.
Thanks,
Karl
Original comment by karlgsch...@gmail.com
on 23 Apr 2009 at 8:14
I think I went a bit too far when I said it is more readable... your point about
having to look for the declaration is a good one. And the second point about
'having'
to change it was maybe mis-communicated, what I meant was if (for whatever
reason)
you had to change a declaration to account for a new interface the same would
apply
to both, so neither way has anything over the other. I admit I was just
spilling out
ideas of how the two approaches compare ;-)
I still see one advantage, however this may also be to do with personal
preference,
consider if I had the call:
MyThing mockMyThing = mock(FirstInterface.class, SecondInterface.class,
ThirdInterfaceWithALongName.class);
If this was happening in a few places I'd probably extract the mocking to a
method of
it's own, if only to save me on typing at least(!), so there's a layer of
indirection
there anyway, and following that is comparable to following the declaration of
Tiger.class in my opinion. If it's done once in a setUp method, I would probably
leave as is, but once again, it's an indirection from a particular test method.
Most of my points were that except under a few conditions* the two approaches
are
pretty much comparable, the difference being that manually crafting your
multiple
interfaces is already there in the Java language, so there's zero effort to do
it
that way.
Regards,
Graham
* with non-default constructors, or when there's not much typing involved, the
mock(...) method is a clear winner
Original comment by Grundlefleck@gmail.com
on 23 Apr 2009 at 9:03
Oh, and when I talked about 'zero effort', I of course meant that in terms of
Mockito
contributor effort! :)
Regards,
Graham
Original comment by Grundlefleck@gmail.com
on 23 Apr 2009 at 9:09
Hello, I see the discussion has warmed up!
Firstly, I don't vote against aspect-style interfaces. What I wanted to see is
some
code that requires to mock multiple interfaces because I have a feeling that we
shouldn't mock them at all :)
Let me try to explain it so you can feedback. I'm going to use some of Misko
Hevery's
nomenclature because I think it's cool. I'm not an ardent reader of his
writings -
I'm just stealing the names and using it quite badly (sorry Misko).
Let's divide objects into 2 categories: injectables (services, DAOs, etc) &
newables
(entities, supporting objects, Strings, spam).
class SomeClass {
EmailService emailService; //injectable
UserRepository userRepository; //injectable
//newable //newable
public User findUser(String name) {...
//newable //newable
public void deleteUser(User user, Reason reason) {...
In most cases, in order to achieve highly maintainable, readable, natural code I
would never mock newables. Only injectables will be mocked if necessary. The
test
should be able to create & use newables with ease - if it cannot then the design
should be changed so that newables are easy to create & use (hint: you'll get
it for
free with TDD :).
Above might sound a bit dogmatic but... well... so be it :) Also, I cannot give
you
any proof that above bold guidelines actually make the code better - that would
require sitting together on some codebase and and some experimenting. (Well, I
could
try to explain it but it could be a lengthy post).
Let's get to the point. From my experience with classes that implement multiple
interfaces it was never required for the injectable to be mocked with multiple
interfaces. Simply because injectable is a statement of dependency - the class
describes that it needs exactly this type in order to work correctly. So I
don't need
to use multi-interface mocking for injectables. I might need it for newables,
though,
but those guys should not really be mocked.
I'm hungry and sleepy now and hopefully what I wrote make sense :)
Original comment by szcze...@gmail.com
on 25 Apr 2009 at 8:09
Well, that's seem very well thought out, but the problem is, I am injecting
these
classes. My base class is a RenderingPipeline, which is a queue for adding 3D
visualization tasks to the display. My aspect interfaces come into play, when
I
have a delegate class for interacting and controling a single aspect:
RenderingPipeline & A. I may have 4 or 5 classes that extend RenderingPipeline
and
implemenet A. If you consider this newable, then the "right way" to test it is
state-based. So, I need to check the state of RenderingPipeline & A, but
that's not
really possible, since it's mainly a rendering engine that produces output. I
could
test that the output of RenderingPipeline & A is expected but now my test
covers two
layers and is dependent on a specific RenderingPipeline & A implementation. I
already have tests to ensure that each RenderingPipeline instance produces
valid
output from valid input. What I want to test is that my controller class which
delegates to this pipeline is performing the correct calls with the correct
parameters. I need to verify behavior, not state, since differing pipeline
produce
different results from the same input.
Original comment by karlgsch...@gmail.com
on 27 Apr 2009 at 3:17
ok, let's do it.
What about a fluent interface like:
mock(Foo.class).alsoImplement(Bar.class, Baz.class)?
Anyone can contribute a patch?
Original comment by szcze...@gmail.com
on 30 Apr 2009 at 3:22
The fluent interface idea is interesting, but mock returns an instance of Foo,
which
doesn't (by default) contain an alsoImplement method. For fluency, I'd
recommend
adding a implementing(Class<?>...interfaces) method and changing mock (or
rather
overloading mock) with:
mock(Foo.class, implementing(Bar.class, Baz.class), "name");
That would add two more mock variants, one for named and unamed mocks.
Possibly
need an additional one for ReturnValues?
implementing() would just return a simple wrapper class used by the other
classes to
add the additional interfaces.
I took a quick look at the source today and I might be able to contribute
something.
Karl
Original comment by karlgsch...@gmail.com
on 5 May 2009 at 4:43
Here's a patch using my implementing() idea. I added some tests to
ClassImposterizerTest and added a TODO in ClassImposterizer. Not sure how you
folks
would want to handle bad input at that point. I didn't add any more test as it
looks like you don't test the statics when the code they rely on is tested.
Anyway, this patch should get you started.
Karl
Original comment by karlgsch...@gmail.com
on 5 May 2009 at 6:02
Attachments:
Cool, I'll look at it. Thanks!
Original comment by szcze...@gmail.com
on 5 May 2009 at 7:34
Ok, it's checked in to trunk but I'm still working on tuning it up
Original comment by szcze...@gmail.com
on 10 May 2009 at 8:42
Ok, done in trunk. The api is as follows:
mock(Foo.class, withSettings().extraInterfaces(Bar.class));
Post here if you have better ideas on the API.
Original comment by szcze...@gmail.com
on 12 May 2009 at 9:07
Original comment by szcze...@gmail.com
on 9 Jun 2009 at 3:15
Original issue reported on code.google.com by
szcze...@gmail.com
on 28 Jan 2009 at 1:52