2012-02-21 138 views
5

我试图在.net中单元测试一个私有函数。这个私有函数返回一个类型为myClass的集合,这是一个内部类。InternalsVisibleTo似乎被忽略

我已经使用程序集属性InternalsVisibleTo,因此myClass类型对我的测试项目是已知的。

这是我想测试代码:

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."); 
} 

,并在我的程序集信息文件:

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

那么,为什么Visual Studio中的列表的类型设置为Class1_Accessor.myClass因为myClass是已知到我的测试项目?

因此,我得到一个运行时错误(无法将类型myClass转换为类型Class1_Accessor.myClass)。

由于myFunction是私有的,VisualStudio中生成以下代码(这是适用于大多数的话)

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

    [Shadowing("[email protected]")] 
    public Class1_Accessor(); 
    public Class1_Accessor(PrivateObject value); 

    public static PrivateType ShadowedType { get; } 

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

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

     [Shadowing("[email protected]")] 
     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); 
    } 
} 

不过,我不明白为什么它包含MyClass的一个新的定义,因为它是一个内部类,它不应该需要任何访问器。我认为这是问题的根源。

+0

您可能想要添加'mstest'标签来吸引那些使用Accessors的人的注意力。我不确定要删除哪个标签,所以我没有自己编辑标签。我从来没有太在意访问者,所以我没有什么经验。 (此外,有一种强烈的观点认为,你不应该测试私人成员;如果你有一个私人成员不是通过公共成员间接测试的,那么这是一个迹象表明你应该为该逻辑提取一个单独的类。) – phoog 2012-02-21 14:46:45

+0

谢谢,我已经添加了标签。测试私人成员是否是一个完全不同的主题(尽管你是对的)。尽管如此,我仍然想测试一个函数。 – Sam 2012-02-21 14:55:30

+0

关于私人成员的测试,这是一个完全不同的话题是我把它放在括号中的原因。当然,这样的指导方针总是有明确的例外。我会补充说,当我*测试私人成员时,我通常只使用反射 - 我甚至为此目的有一些帮助方法(例如'CallNonPublicMethod(string methodName)')。我发现比访问者更容易处理 - 当我修改它们所映射的类时,我从未想出如何让它们重新生成。 – phoog 2012-02-21 15:04:17

回答

0

InternalsVisibleTo不会使私人成员对朋友程序集可见。它适用于标记为内部的成员/类型。检查文档here

更新

试试这个(按照本doc):重新生成测试类,在创建单元测试对话框中,单击设置。在测试生成设置确保荣誉InternalsVisibleTo属性复选框被选中

+1

请再次阅读我的问题。类型myClass IS Internal,不是私有的。这只是我想测试的私有方法。 – Sam 2012-02-21 14:31:30

+2

在你的代码中,myFunction是私人的。 – Fernando 2012-02-21 14:33:53

+0

是的,myFunction是私人的,所以VisualStudio为它创建一个访问器是正常的。但是,myClass是Internal(并且在程序集文件中标记为Friend),所以我不明白为什么VisualStudio会为它创建一个访问器。 – Sam 2012-02-21 14:51:51

4

不能转换MyClass类型为类型Class1_Accessor.myClass

说的一切,我们需要知道:简单 - 你有两个不同的定义的myClass。类型的范围由汇编; [InternalsVisibleTo(...)]使其易于访问,但除此之外:业务照常。

找到为什么/当你拿到一个第二myClass,并之一:

  • 歧义(命名空间限定等)
  • 重命名其中的一个
  • 删除其中的一个,如果他们的意思是相同的的东西,是不正确复制

这是完全一样的有:

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

这是两个完全不相关的类,称为Foo,并且它们之间的投射将失败。