A friend and former colleague of mine, Chris 'Frankie' Salt, recently popped up on Facebook messenger and asked me a question:
“I wonder if you'd mind answering a Java question for me? It's more of a best practices thing. So, encapsulation vs availability of methods for testing. Splitting your code into functions makes it a lot more readable and it makes sense to make these private as they will only ever be used once. However unit testing demands access to these private methods, I know there are ways around this but I was interested in your opinion.”
Me? Have an opinion about unit testing? Many stranger things have happened!
Encapsulation is all about hiding code away so that you can change it with minimal or no impact on other parts of the code base which use it indirectly. You shouldn't (ever) compromise encapsulation for the sake of testing. Every private method you write must be callable from at least one public method or via a chain of other private methods which is ultimately called from a public method. Otherwise, reflection shenanigans aside, it would never get called at all.
Does that mean reflection is the solution to testing private methods? No. It's a great tool for poking values into objects which are initialised using reflection at runtime, so that you don't have to add a public non-default constructor or public setters, but beyond that it should be avoided for testing.
Two solutions sprang to mind, triangulation and sprout classes. Read more.
“I wonder if you'd mind answering a Java question for me? It's more of a best practices thing. So, encapsulation vs availability of methods for testing. Splitting your code into functions makes it a lot more readable and it makes sense to make these private as they will only ever be used once. However unit testing demands access to these private methods, I know there are ways around this but I was interested in your opinion.”
Me? Have an opinion about unit testing? Many stranger things have happened!
Encapsulation is all about hiding code away so that you can change it with minimal or no impact on other parts of the code base which use it indirectly. You shouldn't (ever) compromise encapsulation for the sake of testing. Every private method you write must be callable from at least one public method or via a chain of other private methods which is ultimately called from a public method. Otherwise, reflection shenanigans aside, it would never get called at all.
Does that mean reflection is the solution to testing private methods? No. It's a great tool for poking values into objects which are initialised using reflection at runtime, so that you don't have to add a public non-default constructor or public setters, but beyond that it should be avoided for testing.
Two solutions sprang to mind, triangulation and sprout classes. Read more.
Comments
Post a Comment