Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use PrivateObject to access private members of both my class and its parent?

I'm testing a class that is part of a hierarchy. I've been setting up my test classes with the object under test, and a PrivateObject to allow access to that object. I'm getting exceptions when I attempt to access private members of the parent class.

The only workaround I've found so far is to pass a PrivateType specifying the base class to the PrivateObject constructor, but then it doesn't work on private members of the subclass.

Is there some way I can do this, perhaps by using the binding flags parameter on the Get* methods of Private object?

I did try using the automatically-generated Accessor classes (right-click in the main class, Create Private Accessor). However, that's worse: It shows a property I can read, but it throws the same exception as PrivateObject does, and there's no other options I can use (binding flags or whatnot) to fix the exception.

Here's my sample test code. I'd like there to be some way to construct and use the PrivateObject to retrieve both fields.

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.     } } 
like image 499
David Yaw Avatar asked Mar 22 '11 19:03

David Yaw


People also ask

How do you access private members of parent class?

A class in C++ has public, private and protected sections which contain the corresponding class members. Protected members in a class are similar to private members as they cannot be accessed from outside the class. But they can be accessed by derived classes or child classes while private members cannot.

Can public methods access private variables?

Answer 51c025e6282ae349350092d1 But after the object is created you can only access the private variable through the public methods of the constructor and no longer change it directly in any way.

Which methods can access to private attributes of a class?

Answer: Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself. Private access modifier is more secure and restrictive access level, whereas class and interfaces cannot be private.

What is private object in C#?

Private access specifier allows a class to hide its member variables and member functions from other functions and objects. Only functions of the same class can access its private members. Even an instance of a class cannot access its private members. Create a private variable −


1 Answers

I didn't find the answer, so this is what I ended up doing. I created PrivateObjects for each level of the class's hierarchy, and I just need to be careful when writing test cases that I use the proper one.

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"));     } } 
like image 158
David Yaw Avatar answered Sep 23 '22 02:09

David Yaw