views:

429

answers:

4

I'm jumping into unit-testing the Visual-Studio 2008 way, and I'm wondering what's the best way to accomplish cross-assembly class access for testing purposes.

Basically, I have two projects in one solution:

  1. MyProject (C#)
  2. MyProjectTests (C# Test Project)

Everything in MyProject currently has default accessibility, which if I recall correctly means everything is effectively internal. I'm mostly looking to test at the class level, but there are a few delegates involved.

There will probably be an external API sometime in the future, but I'm about 20% of the way to feature complete (at least on paper) and I'm getting pretty leery of layering more code on top of this untested core. Accordingly I'd like to get some testing done now, before the app is complete enough for traditional (read: bad and/or lazy) functional testing and definitely before the version n+1 external API is up.

In addition to a straight answer, an example of the solution would be greatly appreciated.

+5  A: 

You can use assembly-level attribute InternalsVisibleToAttribute to achieve this.

Add

[assembly:InternalsVisibleTo("MyProjectTests")]

to AssemblyInfo.cs in your MyProject assembly.

Arnold Zokas
With appropriate strong-name key reference included, of course -- you are strong naming your assemblies, aren't you.
Steve Gilham
Of course. :-)
Arnold Zokas
+2  A: 

I created a tutorial for testing this with Internals here. You need to add

[assembly:InternalsVisibleTo("Unit.Tests.Assembly")]

to AssemblyInfo.cs of your "MyProject (C#)". That then allows your tests to access the internal methods for testing

AutomatedTester
+1  A: 

Looks like you need the InternalsVisibleToAttribute

However I'd recommend against this approach - test your internal classes via the public interface or API.

Gishu
Problem is that those don't exist yet; and won't for awhile. Its kind of a large project (or, it will be when completed).
Kevin Montrose
The trouble with the inside out approach is that you may run into a situation where you have the internals done.. but the external API dont plug in as expected - because there was a disconnect in understanding. Feedback comes much later.. when it is more expensive to rectify.
Gishu
True, but putting off thorough testing until the application is "done" is just begging for trouble. Plus, the external API is going to probably take the form of automating user action and extracting data rather than extending functionality; its much harder to screw up compared to a full blown plugin API.
Kevin Montrose
I'm not advocating not testing till the end.. what i am saying is that develop thin vertical slices from the outside in. However you know better about your specific situation - if the risk is minimal it doesn't matter.
Gishu
+1  A: 

Hi,

You can test internal methods, by adding an attribute to the AssemblyInfo.cs for your main project, giving access to the internal methods to a named assembly:

[assembly:InternalsVisibleTo("MyProjectTestsNameSpace.MyProjectTests")]

Further info is here

AdaTheDev