Unit testing is a part of the developers’ life (or at least it should be, if they are smart). However, security and good public interfaces is also something you have to enforce in your company, especially if you are writing an external library.
I saw many times developers making classes public in C# with an excuse that it must be unit tested and apparently your test cases living in another assembly can’t access them if they are not public. It is a valid excuse and it’s arguable what’s better in your situation – exposing private functionality in order to test it and sacrificing the fact that external developers will reference it in their code giving you less space to introduce non breaking changes, or delivering stable code.
You don’t have to make a choice if you know about InternalsVisibleTo attribute. It allows you to open internal types to another assembly and here is how you do it:
- Both code assembly and unit test assembly must be signed. It is a good practice anyway, so go ahead and do it. From visual studio open project properties for both projects and provide the key.
Hint – you can place the key into the root of the solution, reference it as a link in both projects.
- Now you need to get a signature for the unit test project. We need the signature in order to tell the referencing assembly what it can trust. To do that, open console window, navigate to the dll of your unit tests and type the following:
The example is for my opensource Config.Net library which you can find on GitHub.
Now in order to give unit tests library access to the primary assembly with internal classes, open AssemblyInfo.cs in that assembly and add the following attribute:
[assembly: InternalsVisibleTo(“Config.Net.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001008f52c862bf5cd734565cc253e12b17b7779cb73297def09ec2a8215c2ebc11f575c847d50c2f30e7300cca469735c184b88ad7e501e0427cab29825c4389a51edb3e55cbb40c66c4e69c36c00db27af946980c6f854884e771ef4d92aea3f855998404d2f560417169068ab6f1052efcbf3219c266b6f953874c05050abe9bc2”)]
Note that you need that key in one line without line breaks and spaces.
After doing that you’ll notice that unit test assembly can now use classes not marked as public. Happy testing!