EasyMock's Class Extension gives you all that for free.
code: see http://www.easymock.org/EasyMock2_4_ClassExtension_Documentation.html the signature is: createMock(java.lang.Class<T> toMock, java.lang.reflect.Method... mockedMethods)
while this achieves your goal, without need to write additional delegates, I think that in some cases partial mocking is an indicator you need to refactor.
why would you need partial mocking in a real world scenario? that means you want to test your unit in sub-isolation, and that means you can probably split or refactor and reorganize the code.
I think partial mocks should have a huge health warning on them. They imply that there's a role in there that's implicit and that ought to be brought out, and they make refactoring harder. Repeat after me, "Composition over inheritance".
The only time I consider using them is to override a factory method that creates an object that's used internally -- and then only until I can figure out a better plan.
I have read a lot of the papers/docs out right now about using partial mocks, etc. They usually indicate that if you are using them really look at the design of your software. I agree and disagree leading to my predicament:)
I can easily make my object under test a JavaBean style object so that an object that would normally be encapsulated via a "new SomeObject()" can be directly set on the object under test. This is my predicament...usually encapsulation is a good thing making an API easier to program against and less error prone, however when using Mocks (EasyMock in my case) and you want to test, for example a "void" method and ensure that "fileInputStream.close()" gets called in the implementation code, do you expose a "setFileInputStream()" method on the interface or use a partial mock and keep this functionality encapsulated inside a method called, let's say "createInputStream()" which can be partially mocked???
One of the things I really like about following a TDD paradigm with a mock framework such as EasyMock is that it lets you easily test "void" methods and ensure important functionality is actually implemented (for instance inputStream.close()). I just wanted to get others thoughts on "encapsulation vs. ease of testing"...
I guess all we want to say is that partial mock is a warning that the design could be better. Your example describes inputStream.close() as something that can be nicely tested with partial mocks. Say I really need to make sure I never forget to call close(). I would prefer to design the code in a way I cannot forget it. For example (not sure if it makes sense because I'm just making it up :)
This comment has been removed by the author.
ReplyDeleteCool, but I'd rather stick with simple & readable tests which is exact opposite of what you're showing :). Simple tests push simple implementation.
ReplyDeleteEasyMock's Class Extension gives you all that for free.
ReplyDeletecode:
see http://www.easymock.org/EasyMock2_4_ClassExtension_Documentation.html
the signature is: createMock(java.lang.Class<T> toMock, java.lang.reflect.Method... mockedMethods)
while this achieves your goal, without need to write additional delegates, I think that in some cases partial mocking is an indicator you need to refactor.
why would you need partial mocking in a real world scenario? that means you want to test your unit in sub-isolation, and that means you can probably split or refactor and reorganize the code.
I think partial mocks should have a huge health warning on them. They imply that there's a role in there that's implicit and that ought to be brought out, and they make refactoring harder. Repeat after me, "Composition over inheritance".
ReplyDeleteThe only time I consider using them is to override a factory method that creates an object that's used internally -- and then only until I can figure out a better plan.
Here is my predicament...
ReplyDeleteI have read a lot of the papers/docs out right now about using partial mocks, etc. They usually indicate that if you are using them really look at the design of your software. I agree and disagree leading to my predicament:)
I can easily make my object under test a JavaBean style object so that an object that would normally be encapsulated via a "new SomeObject()" can be directly set on the object under test. This is my predicament...usually encapsulation is a good thing making an API easier to program against and less error prone, however when using Mocks (EasyMock in my case) and you want to test, for example a "void" method and ensure that "fileInputStream.close()" gets called in the implementation code, do you expose a "setFileInputStream()" method on the interface or use a partial mock and keep this functionality encapsulated inside a method called, let's say "createInputStream()" which can be partially mocked???
One of the things I really like about following a TDD paradigm with a mock framework such as EasyMock is that it lets you easily test "void" methods and ensure important functionality is actually implemented (for instance inputStream.close()). I just wanted to get others thoughts on "encapsulation vs. ease of testing"...
Karim,
ReplyDeleteI guess all we want to say is that partial mock is a warning that the design could be better. Your example describes inputStream.close() as something that can be nicely tested with partial mocks. Say I really need to make sure I never forget to call close(). I would prefer to design the code in a way I cannot forget it. For example (not sure if it makes sense because I'm just making it up :)
interface InputStreamHandler {
Object handle(InputStream is);
}
class ClosingHandler implements InputStreamHandler {
public ClosingHandler(InputStreamHandler ish) {}
public Object handle(InputStream is) {
//ish.handle & is.close
}
}