Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InternalsVisibleTo seems ignored

I'm trying to unit test a private function in .net. This private function returns a collection of type myClass, which is an internal class.

I've used the assembly attribute InternalsVisibleTo, so that the type myClass is known to my Test project.

Here's the code I want to test:

namespace MyProject
{
    public class Class1
    {
         private List<myClass> myFunction()
         {
             return new List<myClass>();
         }

         internal class myClass
         {
             public int MyProperty { get; set; }
         }   
     }
 }

[TestMethod()]
[DeploymentItem("MyProject.dll")]
public void myFunctionTest()
{
    Class1_Accessor target = new Class1_Accessor(); 
    List<Class1_Accessor.myClass> expected = null; 
    List<Class1_Accessor.myClass> actual;
    actual = target.myFunction();
    Assert.AreEqual(expected, actual);
    Assert.Inconclusive("Verify the correctness of this test method.");
}

and in my assembly info file:

[assembly: InternalsVisibleTo("MyProject.Test")]

So why does Visual Studio set the type of the list to Class1_Accessor.myClass since myClass is known to my test project ?

Because of that I get a runtime error (cannot convert type myClass to type Class1_Accessor.myClass).

Because myFunction is private, VisualStudio generates the following code (which is fine for most of it)

[Shadowing("MyProject.Class1")]
public class Class1_Accessor : BaseShadow
{
    protected static PrivateType m_privateType;

    [Shadowing(".ctor@0")]
    public Class1_Accessor();
    public Class1_Accessor(PrivateObject value);

    public static PrivateType ShadowedType { get; }

    public static Class1_Accessor AttachShadow(object value);
    [Shadowing("myFunction@0")]
    public List<Class1_Accessor.myClass> myFunction();

    [Shadowing("MyProject.Class1+myClass")]
    public class myClass : BaseShadow
    {
        protected static PrivateType m_privateType;

        [Shadowing(".ctor@0")]
        public myClass();
        public myClass(PrivateObject value);

        [Shadowing("MyProperty")]
        public int MyProperty { get; set; }
        public static PrivateType ShadowedType { get; }

        public static Class1_Accessor.myClass AttachShadow(object value);
    }
}

However, I don't understand why it contains a new definition of myClass, since it is an internal class, which shouldn't need any accessor. This is the root of the problem in my opinion.

like image 503
Sam Avatar asked Oct 08 '22 14:10

Sam


1 Answers

cannot convert type myClass to type Class1_Accessor.myClass

says everything we need to know: simply - you have two different definitions of myClass. Types are scoped by assembly; the [InternalsVisibleTo(...)] makes it accessible, but beyond that: business as usual.

Find why/where you have a second myClass, and one of:

  • disambiguate (namespace-qualify etc)
  • rename one of them
  • remove one of them if they mean the same thing, and are incorrectly duplicated

This is exactly the same as having:

namespace A { class Foo {} }
namespace B { class Foo {} }

that is two completely unrelated classes called Foo, and casting between them will fail.

like image 111
Marc Gravell Avatar answered Oct 17 '22 11:10

Marc Gravell