【问题标题】:InternalsVisibleTo seems ignoredInternalsVisibleTo 似乎被忽略了
【发布时间】:2012-03-11 20:39:24
【问题描述】:

我正在尝试在 .net 中对私有函数进行单元测试。这个私有函数返回一个myClass 类型的集合,它是一个内部类。

我使用了程序集属性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(".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);
    }
}

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

【问题讨论】:

  • 您可能需要添加mstest 标签来吸引那些有使用访问器经验的人的注意。我不确定要删除哪个标签,所以我没有自己编辑标签。我从不关心访问者,所以我没有什么经验。 (此外,有一种强烈的观点认为您不应该测试私有成员;如果您有一个不能通过公共成员间接测试的私有成员,那么这表明您应该为该逻辑提取一个单独的类。)跨度>
  • 谢谢,我已经添加了标签。是否测试私人成员是一个完全不同的话题(尽管你是对的)。尽管如此,我仍然想测试那个功能。
  • 关于私人成员的测试,这是一个完全不同的话题,这是我将其放在括号中的原因。当然,这样的指导方针总是有合理的例外。我要补充一点,当我 测试私有成员时,我通常只使用反射——我什至为此目的提供了一些辅助方法(例如,CallNonPublicMethod(string methodName))。我发现这比访问器更容易处理——当我修改它们正在遮蔽的类时,我从来不知道如何让它们重新生成。

标签: visual-studio unit-testing mstest private internal


【解决方案1】:

无法将 myClass 类型转换为 Class1_Accessor.myClass 类型

说明了我们需要知道的一切:简单地说 - 您对 myClass 有两种不同的定义。类型由程序集限定; [InternalsVisibleTo(...)] 使其可访问,但除此之外:一切照旧。

找出为什么/在哪里有第二个myClass,以及以下之一:

  • 消除歧义(命名空间限定等)
  • 重命名其中一个
  • 如果意思相同且重复错误,则删除其中一个

这与拥有完全相同:

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

这是两个完全不相关的类Foo,它们之间的转换会失败。

【讨论】:

    【解决方案2】:

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

    更新

    试试这个(根据这个doc):重新生成您的测试类,在“创建单元测试”对话框中,单击“设置”。在测试生成设置中,确保选中 Honor InternalsVisibleTo 属性复选框

    【讨论】:

    • 请再次阅读我的问题。 myClass 类型是内部的,而不是私有的。只有我想测试的方法是私有的。
    • 是的,myFunction 是私有的,因此 VisualStudio 为其创建访问器是正常的。但是,myClass 是 Internal(并在程序集文件中标记为 Friend),所以我不明白为什么 VisualStudio 会为其创建访问器。
    • 您希望如何在没有访问器的情况下测试私有成员?当 VS 询问您要测试哪些方法时,您可能选择了私有方法。
    • 那很糟糕。 =( 为什么你不能在 Class1 之外拥有 myClass?
    猜你喜欢
    • 2021-10-28
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 2012-03-08
    • 2015-12-11
    • 2014-04-15
    • 1970-01-01
    相关资源
    最近更新 更多