I posted previously about testing non-public members with MbUnit. I recently found out about InternalsVisibleTo attribute by reading Roy Osherove‘s book The Art of Unit Testing.
To use this attribute, your test assembly must be strong-named. Then you put InternalsVisibleTo attribute with public key of test assembly into AssemblyInfo.cs file of assembly under test.
1: [assembly: InternalsVisibleTo("MyAssembly.Tests, PublicKey=XXX")]
I created an Assembly Helper tool that creates the syntax for you. The tool is working (or should work) with following languages:
You can get the tool from here.
Steps to use InternalsVisibleTo attribute with the tool.
Let assume that you have Assm_A and Assm_ATests.
- Sign Assm_A and Assm_ATests with a Strong Name. You can read about that here.
- Compile your assemblies.
- Launch Assembly Helper tool .
- Select desired language and press on ‘Get Assemblies’ button and navigate to Assm_ATests.dll.
- Copy the text into AssemblyInfo file of Assm_A assembly.
Now your tests can access internals members of the assembly under test.
Note: With Assembly Helper tool you can select multiple assemblies at once.
You can actually use this attribute with unsigned assemblies as well.
There is one (undocumented) pitfall you should be aware of:
You can’t have the following attributes in your assemblies:
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile(“”)]
[assembly: AssemblyKeyName(“”)]
Those were used to be included by default in the AssemblyInfo.cs by VS2003. You just need to remove them in order to use the InternalsVisibleTo attribute (called friend assemblies).
Omer,
I don’t think that you can use InternalsVisibleTo attribute without strong-named assembly. Microsoft documentation specifically says: “This attribute can only be applied to strong-named assemblies”.
Anybody try this with delay signed assemblies?
Vadim,
I know that it goes against the documentation, but I can assure you it works.
Hello,
I’m using your tool with a Net 2 mixed model DLL and when I try to use an internal method I get the usual error (OnReceivedMessage is internal).
1>.\ComTests.cpp(166) : error C3767: ‘PimsApi::ComInterface::EventChannelImpCOM::OnReceivedMessage’: candidate function(s) not accessible
I’m putting the attribute
[assembly:InternalsVisibleTo(“PcsPims500.IntegrationTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010069EB6CD4E0E36EF1992E8DA1646C97270C48FE5DBF6936655757D545B71FF22AD01BF2F470EABBB02D7B66CA9DD58D920FA62E4C46D4F721616B1680D6098D51ED81D8ED2107AE533151D13B86165B806AAF25E878A56BF8A23F3E86FAFC3E6F016F2CF8B82A9F887068C21F37D5616F9314D2D170781ED2915BF56BB1F6A5CD”)]
at the AssemblyInfo file of the assembly that must open its internals to a integrationtests DLL.
Any hint? I’m lost with this one.
Did you put InernalsVisibleTo attribute in PimsApi or PcsPims500.IntegrationTests assembly?
Hello Vadim, thanks for your answer. I thougth on this one and I added the attribute to PimsApi because this is the one that must expose its internal methods. Is that rigth?
Thanks again for your time.
This is correct. You should add the attribute to PimsApi.
Attractive portion of content. I just stumbled upon your web site and in accession capital to claim that I acquire in fact
loved account your blog posts. Any way I’ll be subscribing in your feeds or even I fulfillment you access consistently rapidly.
Great utility … it would be great if it let go of the assembly after generating the attribute code. My build was failing because I still had it open.