Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Do access modifiers limit unit testing?

Status
Not open for further replies.

mattriley

Programmer
May 26, 2010
3
AU
I often find what I believe are good cases for using the "internal" access modifier on certain class members in C# for code readability and to prevent unintended usage. In .NET we usually write our unit tests in a separate unit test project. Problem is, class members marked as internal are not visible to the test project and can be cumbersome to test. I understand there are workarounds such as the "InternalsVisibleTo" attribute, reflection or Visual Studio generated "accessor" classes but I wonder if the goal can be achieved with a better OO design. Is it worth compromising testability by using internal class members, or do they provide enough benefit to justify their use? I've heard suggestions such as "just make it public", but I don't feel that's a trade-off I should have to make. Any opinions here?
 
I usually go with "just make it public". The objects within my service layer and domain are simple enough, that I know what to look for. I'm also the only programmer, so I know the entire code base.

One idea I read about recently was non-public ctors for domain objects. the example was a shopping cart. the cart's ctor was internal, so from the public API the client knew you had to create a shopping cart by some means other than new ShoppingCart();

as for members (properties/functions) I believe this is where the SRP and ISP come into play. by designing intention revealing interfaces and placing the public API in a common top level namespace you encourage the client to use the intended API, rather than guess at "how do I...".

another thought, look at some of the open source projects. how they structure their API and test the code. I find this is a good learning tool as well. Castle has very clean code and the public API of NHibernate is *easy* to use too. This may give you some ideas.

another thought: test "internal" members as integration tests. test a set of concrete implementations as a whole. Unit Test help drive out design, but there is still the issue of the system meeting the business requirement. For that integration tests are needed. In that sense the public/private doesn't matter as much as providing a solution for a given requirement. example:
as a customer
when I submit an order and I have bad credit
i should have my order rejected

this type of test has business meaning and is ultimately what determines if the system works or not. how that is implemented doesn't matter, so much.

I know where your coming from. I have been there myself, and often come back to that same question. In my current situation I can afford to "just make it public" without compromising the code base.
I haven't used InternalsVisibleTo, but this would be the next logical step for me.

Jason Meckley
Programmer
Specialty Bakers, Inc.

faq855-7190
faq732-7259
 
Thanks jmeckley for your reply. I agree regarding non-public constructors, particularly where a factory is the intended means of producing an object. I also agree with revealing interfaces in a common top-level namespace. I've heard that this is particularly common in the Java community, and that concrete objects should be treated simply as "implementation details" and should reside in a sub-namespace that indicates this, for example, a ".Impl" namespace. As long as the convention is understood, there's no reason to need to use restrictive access modifiers on the concrete types.

Is anyone in the practice of using this approach (Java or .NET)?
 
I have seen this in approach in some of the Rhino.Tools frameworks.

Jason Meckley
Programmer
Specialty Bakers, Inc.

faq855-7190
faq732-7259
 
As long as the convention is understood, there's no reason to need to use restrictive access modifiers on the concrete types."

But humans are involved......
 
Hi Craig. Yes, that's the whole point. How do we compromise between access modifiers and unit testability? I'm also finding that developers who practice true TDD are more likely to be lenient with access modifiers. I'd be interested in hearing from such developers.
 
I cannot speak for the other forums like java, php, etc. As for .net developers; I have been on tek-tips since 2002 and I have only come across a handful of developers who know what unit testing is, much less what TDD is.

you may what to check out The book is considered by some to be the foundation of good testing skills. Roy (the author) is a unit testing guru. If his blog doesn't have any information, you could send him an email. I'm fairly sure he would respond.

Another good resource I have found is design principles are the the primary driving force behind this website. testing is frequently mentioned as well. this may provide some insight.

finally, jimmy bogard did a series not too long about domain driven design. there are a few points where he talks about access modifiers and unit testing. jimmy's blog is on los techies, so it should not be too hard to find.

Jason Meckley
Programmer
Specialty Bakers, Inc.

faq855-7190
faq732-7259
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top