72

I insert the line:

[assembly: InternalsVisibleTo("MyTests")]

inside my project under test( Properties/AssemblyInfo.cs) where MyTests is the name of the Unit Test project. But for some reason I still cannot access the internal methods from the unit test project.

Any ideas about what I am doing wrong ?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Cemre Mengü
  • 18,062
  • 27
  • 111
  • 169
  • 1
    It's been a looong time but I think the two assemblies have to be signed with the same signature? – Joe Sep 17 '13 at 09:07
  • possible duplicate of [InternalsVisibleTo attribute isn't working](http://stackoverflow.com/questions/106880/internalsvisibleto-attribute-isnt-working) – Jon Sep 17 '13 at 09:08
  • I read that on a question in SO but I am not sure if that may create problems in the future. I also couldnt manage to sign my assemblies. – Cemre Mengü Sep 17 '13 at 09:09
  • @Cemre: You don't need to sign, if both assemblies are unsigned it should all work. But do read the answers to the linked question. – Jon Sep 17 '13 at 09:10

7 Answers7

81

If your assembly is signed with a strong name look at this answer.

Otherwise check that the name of your test assembly really is "MyTests.dll" (it doesn't have to match the project name, though it will by default).

Community
  • 1
  • 1
Joe
  • 122,218
  • 32
  • 205
  • 338
  • 15
    +1 yep, I remember wasting some time on this issue : the assembly _file system name_ of the test app was different than its project name :) – Shmil The Cat Sep 21 '14 at 11:05
  • +1 as well. The default class or unit test name is valid, but never what I will have renamed it by the time it gets published. The resulting .dll will retain the first saved file name until the 'Assembly name' is changed in the project's properties. – Vic Colborn Apr 12 '16 at 20:17
  • When your projects are unsigned also make sure that the application project (the one containing the `[assembly: InternalsVisibleTo("MyTests")]` friend reference) does not contain `[assembly: AssemblyKeyName("")]` in its AssemblyInfo.cs file. – AlwaysLearning Jan 14 '19 at 02:36
16

Let's break it down a bit as many of us have experienced this slight mix-up in the past...

Assembly A has your internal class. Assembly B has your unit tests.

You wish to grant the internals of assembly A visibility in assembly B.

You need to put the InternalsVisibleTo assembly attribute inside assembly A and grant access to assembly B.

Pang
  • 9,564
  • 146
  • 81
  • 122
Observer
  • 755
  • 1
  • 14
  • 23
6

I had the same issue after renaming a namespace. Basically the in .cs files was the new namespace but in the .csproj and AssemblyInfo.cs it was the old namespace.

namespace newNamespace {
   ....
}

So, I changed in .csproj the following to the new namespace:

    <RootNamespace>oldnamespace</RootNamespace>
    <AssemblyName>oldnamespace</AssemblyName>

And in AssemblyInfo.cs:

[assembly: AssemblyTitle("oldnamespace")]
[assembly: AssemblyProduct("oldnamespace")]
RJFalconer
  • 10,890
  • 5
  • 51
  • 66
Alin Ciocan
  • 3,082
  • 4
  • 34
  • 47
5

You still need your test project to reference your main project.

This can be easy to overlook and if you have no existing test code this may appear like the InternalsVisibleTo is not functioning.

Joseph Lennox
  • 3,202
  • 1
  • 27
  • 25
3

In my case I was coding to an Interface. As interfaces can only specify public properties the internal properties were not present on the interface.

Make sure you're not doing the same thing as I was!

I changed:

Assert.IsNotNull((exportFileManager)?.ThumbnailFileExporter);

To:

Assert.IsNotNull((exportFileManager as ExportFileManager)?.ThumbnailFileExporter);
K-Dawg
  • 3,013
  • 2
  • 34
  • 52
  • 1
    Took me forever to find this answer. Cannot understand why the internal explicitly declared implementation of the interface was not recognized, – Sentinel Mar 29 '18 at 15:48
  • 2
    Explicitly implemented methods are never visible (that's the point); you have to cast the object to the interface in order to get access to those method implementations. – BrainSlugs83 May 07 '18 at 21:02
  • @BrainSlugs83 don't you mean cast the interface to the concrete class? Sure, I understand why it happens but my point it that it's an easy mistake to make perhaps without realising. – K-Dawg May 23 '18 at 04:08
2

I made the incorrect assumption that InternalsVisibleTo will help in accessing Private methods too.

Here are some other aspects that can lead to this error:

  • Your class is either internal or public
  • Your method is internal
  • The InternalsVisibleTo property contains the full namespace of your test project.
Sudharshann D
  • 935
  • 9
  • 9
0

You can expose internals from strong named assembly to another strong named friend assembly only. But non-strong named assembly can expose internals to strong named friend assembly.