views:

3104

answers:

5

I'm new in unit testing and I'm trying to figure out if I should start using more of 'internal' access modifier. I know that if we use 'internal' and set the assembly variable 'InternalsVisibleTo', we can test functions that we don't want to declare public from the testing project. This makes me think that I should just always use 'internal' because at least each project (should?) has it's own testing project. Can you guys tell me a reason why I shouldn't do this? When should I use 'private'?

+4  A: 

You can use private as well and you can call private methods with reflection. If you're using Visual Studio Team Suite it has some nice functionality that will generate a proxy to call your private methods for you. Here's a code project article that demonstrates how you can do the work yourself to unit test private and protected methods:

http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx

In terms of which access modifier you should use, my general rule of thumb is start with private and escalate as needed. That way you will expose as little of the internal details of your class as are truly needed and it helps keep the implementation details hidden, as they should be.

Steven Behnke
+6  A: 

In theory you should only need to test your public methods anyway. Just have enough tests that you are testing all the code paths. In reality you may want to verify something works as expected before calling it wth a whole lot more code.

If you are using TDD (Test Driven Development) this is not usually an issue as no code is written without a test so no code path should remain untested. Internal, protected and private methods are then spawned as you refactor against your existing tests.

The problem comes when you aren't using TDD and have to fit tests into already written code. Then you might want to test individual methods without making them public.

There are ways and means you can do that. VS2008 offers a helper to generate internal accessors which you can use to test internal methods. Or you can roll your own by using protected (not private methods) and inheritance.

Brody
+2  A: 

If you want to test private methods, have a look at PrivateObject and PrivateType in the Microsoft.VisualStudio.TestTools.UnitTesting namespace. They offer easy to use wrappers around the necessary reflection code.

Brian Rasmussen
+1  A: 

Keep using private by default. If a member shouldn't be exposed beyond that type, it shouldn't be exposed beyond that type, even to within the same project. This keeps things safer and tidier - when you're using the object, it's clearer which methods you're meant to be able to use.

Having said that, I think it's reasonable to make naturally-private methods internal for test purposes sometimes. I prefer that to using reflection, which is refactoring-unfriendly.

One thing to consider might be a "ForTest" suffix:

internal void DoThisForTest(string name)
{
    DoThis(name);
}

private void DoThis(string name)
{
    // Real implementation
}

Then when you're using the class within the same project, it's obvious (now and in the future) that you shouldn't really be using this method - it's only there for test purposes. This is a bit hacky, and not something I do myself, but it's at least worth consideration.

Jon Skeet
If the method is internal does this not preclude its use from the testing assembly?
Ralph Shillington
@Ralph: Not using InternalsVisibleTo.
Jon Skeet
+11  A: 

Internal classes need to be tested and there is an assemby attribute:

using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("MyTests")]
EricSchaefer
Do I add this to the test project or to the project under test !?!?
Adrian
Add it to the project under test (e.g. in Properties\AssemblyInfo.cs). "MyTests" would be the test assembly.
EricSchaefer