views:

334

answers:

2

I have written quite a few Mock objects using EasyMock. However, often i find writing partial mocks time consuming, and it does not feel 'right'.

I'd say its a design fault as my class I try to mock has multiple concerns into one, therefore I should create seperate classes in order to seperate concerns.

What do you think? Is partially mocking a good or bad thing? And, if good/bad, why? What would you suggest if you notice you cannot mock the object because you only want to mock a few methods?

A: 

I personally am not a fan of partial mocks because it means that your test of ClassA then depends in some part on the behavior of ClassB - and the point of mocking is to be able to test ClassA independent of any implementation details of any of it's colloborators.

I'm confused on what you mean by "you only want to mock a few methods". What version of EasyMock are you using? Typically you only need to supply expectations and return values for the methods that will actually be called. Or do you mean that you are writing stub versions of these classes?

If you are concerned that your colloborator "has multiple concerns into one", you could always try to break up it's interface into several different interfaces - and the implementation class can just implement all of them. This way, you can supply different mocks in your unit test (one per interface), even if your implementation is still just a single class.

matt b
If you want to test method X in class A. Method X calls Method Y and Z of Class A aswell. Come to think of it. I only used partially mocking once and later on stubbed all the methods i wanted to 'partially mock away'. I see you're saying it is bad design also, correct?About the multiple concerns into one, yes I figured multiple interfaces might do the trick. But I am kinda afraid of the enormous amount of classes you generate. Also, a lot of things are written twice needing refactoring, sounds like a lot of extra work?
Stefan Hendriks
Creating N interfaces just means creating N new .java files for each interface definition. What I was referring to was breaking up your mega-dependency in ClassA on ClassB into several interfaces, but just have ClassBImpl implement all of those interfaces.
matt b
Mocking and "coding to the interface" actually help reduce the amount of changes you have to make during refactoring, since it clearly breaks code and classes down into modules that know how to interface with each other but not all of the details of each other.
matt b
You mean use interfaces to add characteristics? Ie, lets say i have a POJO "email". You would apply an interface to it to make it 'serializeToXML' ? Ie, an XMLSerializable interface?
Stefan Hendriks
No. I think we are misunderstanding each other.
matt b
+2  A: 

If you find yourself creating partial mocks on a regular basis, it might be a sign that too much state and functionality is being thrown into a small number of classes. This can make your code more difficult to maintain and reason about and consequently harder to unit test. It can also lead to code duplication or circular dependencies if you find out later that some other component in your system needs a subset of the functionality contained in one of your large classes.

Try to identify related groups of functionality and break those out into smaller helper classes that can be unit tested independently. This will make the code easier to understand, enables you to write finer-grained unit tests, and you may find opportunities to reuse the functionality you've split out in different contexts sometime in the future. If you're using a dependency injection framework like Spring or Guice, it will be easy to wire those objects back together when your application runs.

Figuring out the best way to refactor large classes is something one learns through experience. Generally, though, I try to look at what a class is doing and give names to the different roles it plays at different points in processing. Then I create new classes for those roles. For example, if I had a class that reads through a server log file and emails an administrator when certain entries are found there, I might refactor that into one class that knows how to parse log files, a second class that looks for the trigger entries, and a third that knows how to notify administrators. The trick is to limit how much "knowledge" is contained in each class. This also gives you the opportunity to abstract out general concepts. For example, by breaking your classes up this way, you could support different notification mechanisms or kinds of trigger conditions in the future without impacting your log parsing class or its unit test.

Rob H
Thanks a lot for your answer (i can't give points yet, sorry). I think you hit the spot.What i found hard about seperating concerns is that I get so many little classes. Eventually i have the same class I had but with a huge constructor using all those little helper classes. (ie, class A has ... X, Y, Z).
Stefan Hendriks
That's a danger, yes. You gotta strike a balance.
Rob H