类中具有重载构造函数C#单元测试的私有成员

本文关键字:单元测试 成员 构造函数 重载 | 更新日期: 2023-09-27 18:21:44

如何在单元测试中访问私有成员?我尝试使用PrivateObject,但重载构造函数在这里,并且我得到了_inkContainerValue的错误。我可以在不使用类对象的情况下访问私人成员吗?

  public class Pen
   {
    private int _inkContainerValue = 1000;
    #region Constructors
    public Pen(int inkContainerValue)
    {
        this._inkContainerValue = inkContainerValue;
    }
    #endregion
    }

}

类中具有重载构造函数C#单元测试的私有成员

PrivateObject pObj = new PrivateObject(typeof(Pen));
int privateInkContainerValue = (int)pObj.GetField("_inkContainerValue");

请尝试上面的代码,通过单元测试中的PrivateObject类获取_inkContainerValue字段的值。

// Following is overloaded version to pass value to actual Pen class's constructor.
PrivateObject pObj = new PrivateObject(typeof(Pen), new object[]{12});
int privateInkContainerValue = (int)pObj.GetField("_inkContainerValue");

我现在没带编辑。语法应该是理想的工作方式。

我可以在不使用类对象的情况下访问私人成员吗?

没有。您必须拥有一个对象的实例,才能从该对象中提取数据。

无意冒犯,但由于构造函数重载,您对使用反射的犹豫似乎没有意义。如果你有一个实例,它不应该阻止你使用反射,或者如果你没有,它不可以阻止你创建一个实例。

下面是一个使用Reflection从_ink中获取值的示例。它还向您展示了如何在不使用构造函数的情况下获得实例。但是,请记住不会初始化任何_ink将是0,而不是您在代码中看到的1000

public class Pen
{
    int _ink = 1000;
    public Pen(int ink)
    {
        _ink = ink;
    }
}
void Test()
{
    //Create the object and check constructor set the value
    var pen = new Pen(5);
    var field = pen.GetType().GetField("_ink", BindingFlags.NonPublic|BindingFlags.Instance);
    // This should pass.
    Debug.Assert((int)field.GetValue(pen) == 5);
    // Create the pen without using constructor. 
    // No matter what, nothing is initialized meaning _ink is 0 and not 1000.
    // Hence, uninitialized.
    var uninitializedPen = (Pen)FormatterServices.GetUninitializedObject(typeof(Pen));
    field = uninitializedPen.GetType().GetField("_ink", BindingFlags.NonPublic|BindingFlags.Instance);
    //This will fail.
    Debug.Assert((int)field.GetValue(uninitializedPen) == 1000);
}

为了使用FormatterServices类,您需要导入System.Runtime.Serialization命名空间。