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 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 :)
Cool, but I'd rather stick with simple & readable tests which is exact opposite of what you're showing :). Simple tests push simple implementation.
ReplyDeleteI 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.
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
}
}