如何使用PrivateObject访问我的类及其父级的私有成员?

Dav*_*Yaw 24 c# unit-testing mstest

我正在测试一个属于层次结构的类.我一直在用测试对象设置我的测试类,并且PrivateObject允许访问该对象.当我尝试访问父类的私有成员时,我遇到异常.

到目前为止,我发现的唯一解决方法是将PrivateType指定基类传递给PrivateObject构造函数,但是它不适用于子类的私有成员.

有没有办法可以做到这一点,也许是通过在Private对象的Get*方法上使用绑定flags参数?

我尝试使用自动生成的Accessor类(右键单击主类,Create Private Accessor).然而,情况更糟:它显示了我可以读取的属性,但它抛出与PrivateObject相同的异常,并且没有其他选项可以使用(绑定标志或诸如此类)来修复异常.

这是我的示例测试代码.我希望有一些方法来构造和使用PrivateObject来检索这两个字段.

public class BaseClass
{
    private int one = 1;
}

public class SubClass : BaseClass
{
    private int two = 2;
}

[TestClass]
public class UnitTest1
{
    BindingFlags flags = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

    [TestMethod]
    public void TestMethod1()
    {
        SubClass test = new SubClass();
        PrivateObject priv = new PrivateObject(test);

        Assert.AreNotEqual<int>(0, (int)priv.GetFieldOrProperty("one", flags)); // System.MissingMethodException: Method 'PrivateObjectTester.SubClass.one' not found.
        Assert.AreNotEqual<int>(0, (int)priv.GetFieldOrProperty("two", flags));
    }

    [TestMethod]
    public void TestMethod2()
    {
        SubClass test = new SubClass();
        PrivateObject priv = new PrivateObject(test, new PrivateType(typeof(BaseClass)));

        Assert.AreNotEqual<int>(0, (int)priv.GetFieldOrProperty("one", flags));
        Assert.AreNotEqual<int>(0, (int)priv.GetFieldOrProperty("two", flags)); // System.MissingMethodException: Method 'PrivateObjectTester.BaseClass.two' not found.
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*Yaw 33

我找不到答案,所以这就是我最终要做的事情.我PrivateObjects为类的层次结构的每个级别创建,我只需要在编写使用正确的测试用例时要小心.

public class BaseClass
{
    private int one = 1;
}

public class SubClass : BaseClass
{
    private int two = 2;
}

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod()
    {
        SubClass test = new SubClass();
        PrivateObject privSub = new PrivateObject(test, new PrivateType(typeof(SubClass)));
        PrivateObject privBase = new PrivateObject(test, new PrivateType(typeof(BaseClass)));

        Assert.AreNotEqual<int>(0, (int)privBase.GetFieldOrProperty("one"));
        Assert.AreNotEqual<int>(0, (int)privSub.GetFieldOrProperty("two"));
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 10

这可能不是你想要的答案......但你不应该首先在一个方法中测试这两个类.你应该一次只测试一个班级.如果你觉得有必要这样做,那么我猜你的代码需要重构.但由于我不知道你的现实代码问题,我不能肯定地说

  • 我并没有真正测试两个类,我正在测试一个类,以及它的基类.在我的情况下,我正在测试一些清理行为:当对象清理自己时,我正在检查所有清理任务是否已正确发生,其中一些是在基础中,一些在子类中.你是对的,理想情况下,我应该自己测试基类清理,但是这个测试的一部分是测试只有这个特定子类才会发生的异常清理. (2认同)