Private Accessor

The Telerik JustMock PrivateAccessor feature allows you to call non-public members of the tested code right in your unit tests. The feature is enabled for both Free and Commercial versions of JustMock.

To give examples of how the PrivateAccessor can be used within your tests, we will use the following sample class:

public class ClassWithNonPublicMembers 
{ 
    private int Prop { get; set; } 
 
    private int MePrivate() 
    { 
        return 1000; 
    } 
 
    private static int MeStaticPrivate() 
    { 
        return 2000; 
    } 
 
    private T EchoPrivateGeneric<T>(T arg) 
    { 
        return arg; 
    } 
 
    private static T EchoStaticPrivateGeneric<T>(T arg) 
    { 
        return arg; 
    } 
} 
Public Class ClassWithNonPublicMembers 
    Private Property Prop() As Integer 
        Get 
            Return m_Prop 
        End Get 
        Set(value As Integer) 
            m_Prop = Value 
        End Set 
    End Property 
    Private m_Prop As Integer 
 
    Private Function MePrivate() As Integer 
        Return 1000 
    End Function 
 
    Private Shared Function MeStaticPrivate() As Integer 
        Return 2000 
    End Function 
 
    Private Function EchoPrivateGeneric(Of T)(ByVal arg As T) As T 
        Return arg 
    End Function 
 
    Private Shared Function EchoStaticPrivateGeneric(Of T)(ByVal arg As T) As T 
        Return arg 
    End Function 
End Class 

Calling Private Methods

The next example will show how to invoke non-public method with the PrivateAccessor:

[TestMethod] 
public void PrivateAccessor_ShouldCallMethod() 
{ 
    // Act 
    var inst = new PrivateAccessor(new ClassWithNonPublicMembers()); 
    var actual = inst.CallMethod("MePrivate"); 
 
    // Assert 
    Assert.AreEqual(1000, actual); 
} 
<TestMethod> _ 
Public Sub PrivateAccessor_ShouldCallMethod() 
    ' Act 
    Dim inst = New PrivateAccessor(New ClassWithNonPublicMembers()) 
    Dim actual = inst.CallMethod("MePrivate") 
 
    ' Assert 
    Assert.AreEqual(1000, actual) 
End Sub 

To call non-public methods with PrivateAccessor you must:

  1. Wrap the instance holding the private method
  2. Call the non-public method by giving its exact name
  3. Finally, you can assert against its value

Next, we will show how to call non-public methods from a mocked instance:

[TestMethod] 
public void ShouldCallArrangedPrivateMethod() 
{ 
    // Arrange 
    var mockedClass = Mock.Create<ClassWithNonPublicMembers>(Behavior.CallOriginal); 
 
    Mock.NonPublic.Arrange<int>(mockedClass, "MePrivate").Returns(5); 
 
    // Act 
    var inst = new PrivateAccessor(mockedClass); 
    var actual = inst.CallMethod("MePrivate"); 
 
    // Assert 
    Assert.AreEqual(5, actual); 
} 
<TestMethod> _ 
Public Sub ShouldCallArrangedPrivateMethod() 
    ' Arrange 
    Dim mockedClass = Mock.Create(Of ClassWithNonPublicMembers)(Behavior.CallOriginal) 
 
    Mock.NonPublic.Arrange(Of Integer)(mockedClass, "MePrivate").Returns(5) 
 
    ' Act 
    Dim inst = New PrivateAccessor(mockedClass) 
    Dim actual = inst.CallMethod("MePrivate") 
 
    ' Assert 
    Assert.AreEqual(5, actual) 
End Sub 
  1. Create a mocked instance of your class under test (you can also use original instance object and perform partial mocking later on)
  2. Arrange your expectations
  3. Then, create new PrivateAccessor with the mocked instance as an argument
  4. Call the non-public method by giving its exact name
  5. Finally, you can assert against its expected return value

Using the steps above and supplying the type arguments you can call non-public generic methods, the sample test looks as following:

[TestMethod] 
public void ShouldCallArrangedPrivateGenericMethod() 
{ 
    // Arrange 
    var mockedClass = Mock.Create<ClassWithNonPublicMembers>(Behavior.CallOriginal); 
 
    Mock.NonPublic.Arrange<int>(mockedClass, "EchoPrivateGeneric", new Type[] { typeof(int) }, 10).Returns(5); 
 
    // Act 
    var inst = new PrivateAccessor(mockedClass); 
    var actual = inst.CallMethodWithTypeArguments("EchoPrivateGeneric", new Type[] { typeof(int) }, 10); 
 
    // Assert 
    Assert.AreEqual(5, actual); 
} 
<TestMethod> 
Public Sub ShouldCallArrangedPrivateGenericMethod() 
    ' Arrange 
    Dim mockedClass = Mock.Create(Of ClassWithNonPublicMembers)(Behavior.CallOriginal) 
 
    Mock.NonPublic.Arrange(Of Integer)(mockedClass, "EchoPrivateGeneric", New Type() {GetType(Integer)}, 10).Returns(5) 
 
    ' Act 
    Dim inst = New PrivateAccessor(mockedClass) 
    Dim actual = inst.CallMethodWithTypeArguments("EchoPrivateGeneric", New Type() {GetType(Integer)}, 10) 
 
    ' Assert 
    Assert.AreEqual(5, actual) 
End Sub 

Calling Static Private Methods

The next example will show how to invoke non-public static method with the Telerik JustMock PrivateAccessor:

[TestMethod] 
public void PrivateAccessor_ShouldCallStaticMethod() 
{ 
    // Act 
    var inst = PrivateAccessor.ForType(typeof(ClassWithNonPublicMembers)); 
    var actual = inst.CallMethod("MeStaticPrivate"); 
 
    // Assert 
    Assert.AreEqual(2000, actual); 
} 
<TestMethod> _ 
Public Sub PrivateAccessor_ShouldCallStaticMethod() 
    ' Act 
    Dim inst = PrivateAccessor.ForType(GetType(ClassWithNonPublicMembers)) 
    Dim actual = inst.CallMethod("MeStaticPrivate") 
 
    ' Assert 
    Assert.AreEqual(2000, actual) 
End Sub 

To call non-public static methods with the PrivateAccessor you must:

  1. Wrap the instance holding the private method by type
  2. Call the non-public static method by giving its exact name
  3. Finally, you can assert against its value

Next, we will show how to call non-public static methods from a mocked instance:

[TestMethod] 
public void ShouldCallArrangedStaticPrivateMethod() 
{ 
    // Arrange 
    Mock.SetupStatic(typeof(ClassWithNonPublicMembers)); 
 
    Mock.NonPublic.Arrange<int>(typeof(ClassWithNonPublicMembers), "MeStaticPrivate").Returns(5); 
 
    // Act 
    var inst = PrivateAccessor.ForType(typeof(ClassWithNonPublicMembers)); 
    var actual = inst.CallMethod("MeStaticPrivate"); 
 
    // Assert 
    Assert.AreEqual(5, actual); 
} 
<TestMethod> _ 
Public Sub ShouldCallArrangedStaticPrivateMethod() 
    ' Arrange 
    Dim mockedClass = Mock.Create(Of ClassWithNonPublicMembers)(Behavior.CallOriginal) 
 
    Mock.NonPublic.Arrange(Of Integer)(mockedClass, "MeStaticPrivate").IgnoreInstance().Returns(5) 
 
    ' Act 
    Dim inst = PrivateAccessor.ForType(GetType(ClassWithNonPublicMembers)) 
    Dim actual = inst.CallMethod("MeStaticPrivate") 
 
    ' Assert 
    Assert.AreEqual(5, actual) 
End Sub 
  1. Setup your class for static mocking (this is not needed if you are to perform partial mocking later on)
  2. Arrange your expectations
  3. Then, create new PrivateAccessor with the mocked instance type as an argument
  4. Call the non-public method by giving its exact name
  5. Finally, you can assert against its expected return value

Like a non-public generic instance methods, you can use PrivateAccessor to call non-public generic static ones, here is the sample test:

[TestMethod] 
public void ShouldCallArrangedStaticPrivateGenericMethod() 
{ 
    // Arrange 
    Mock.SetupStatic(typeof(ClassWithNonPublicMembers)); 
 
    Mock.NonPublic.Arrange<int>(typeof(ClassWithNonPublicMembers), "EchoStaticPrivateGeneric", new Type[] { typeof(int) }, 10).Returns(5); 
 
    // Act 
    var inst = PrivateAccessor.ForType(typeof(ClassWithNonPublicMembers)); 
    var actual = inst.CallMethodWithTypeArguments("EchoStaticPrivateGeneric", new Type[] { typeof(int) }, 10); 
 
    // Assert 
    Assert.AreEqual(5, actual); 
} 
<TestMethod> 
Public Sub ShouldCallArrangedStaticPrivateGenericMethod() 
    ' Arrange 
    Mock.SetupStatic(GetType(ClassWithNonPublicMembers)) 
 
    Mock.NonPublic.Arrange(Of Integer)(GetType(ClassWithNonPublicMembers), "EchoStaticPrivateGeneric", New Type() {GetType(Integer)}, 10).Returns(5) 
 
    ' Act 
    Dim inst = PrivateAccessor.ForType(GetType(ClassWithNonPublicMembers)) 
    Dim actual = inst.CallMethodWithTypeArguments("EchoStaticPrivateGeneric", New Type() {GetType(Integer)}, 10) 
 
    ' Assert 
    Assert.AreEqual(5, actual) 
End Sub 

Get or Set Private Properties

The next example shows how to get or set the value of a non-public property.

[TestMethod] 
public void PrivateAccessor_ShouldGetSetProperty() 
{ 
    // Act 
    var inst = new PrivateAccessor(new ClassWithNonPublicMembers()); 
    inst.SetProperty("Prop", 555); 
 
    // Assert 
    Assert.AreEqual(555, inst.GetProperty("Prop")); 
} 
<TestMethod> _ 
Public Sub PrivateAccessor_ShouldGetSetProperty() 
    ' Act 
    Dim inst = New PrivateAccessor(New ClassWithNonPublicMembers()) 
    inst.SetProperty("Prop", 555) 
 
    ' Assert 
    Assert.AreEqual(555, inst.GetProperty("Prop")) 
End Sub 

In the above example, we are: 1. Passing the instance holding the private property to the PrivateAccessor 1. Setting the value of the private property Prop to 555 1. Asserting that, the getter of Prop must return the above set value

Next, we will show how to get an arranged non-public property from a mocked instance:

[TestMethod] 
public void ShouldGetArrangedPrivateProperty() 
{ 
    // Arrange 
    var mockedClass = Mock.Create<ClassWithNonPublicMembers>(Behavior.CallOriginal); 
 
    Mock.NonPublic.Arrange<int>(mockedClass, "Prop").Returns(5); 
 
    // Act 
    var inst = new PrivateAccessor(mockedClass); 
    var actual = inst.GetProperty("Prop"); 
 
    // Assert 
    Assert.AreEqual(5, actual); 
} 
<TestMethod> _ 
Public Sub ShouldGetArrangedPrivateProperty() 
    ' Arrange 
    Dim mockedClass = Mock.Create(Of ClassWithNonPublicMembers)(Behavior.CallOriginal) 
 
    Mock.NonPublic.Arrange(Of Integer)(mockedClass, "Prop").Returns(5) 
 
    ' Act 
    Dim inst = New PrivateAccessor(mockedClass) 
    Dim actual = inst.GetProperty("Prop") 
 
    ' Assert 
    Assert.AreEqual(5, actual) 
End Sub 
  1. Create a mocked instance of your class under test (you can also use original instance object and perform partial mocking later on)
  2. Arrange your expectations
  3. Then, create new PrivateAccessor with the mocked instance as an argument
  4. Set the non-public property by giving its exact name
  5. Finally, you can assert against its expected return value

Throw the original exception when calling method

PrivateAccessor is using the reflection API to invoke the required method. When that method throws exception the reflection API is automatically wrapping it in a TargetInvocationException. This could cause inconvenience in determining what the original problem is. PrivateAccessor.RethrowOriginalOnCallMethod is a boolean property that solves that problem by controling whether the original exception should be thrown or not. For backward compatibility the default value is false. To better illustrate the usage of this property consinder the following code sample:

public class Foo 
{ 
    private void ThrowsException() 
    { 
        throw new NotImplementedException("There is no implementation for this method."); 
    } 
} 
Public Class Foo 
    Private Sub ThrowsException() 
        Throw New NotImplementedException("There is no implementation for this method.") 
    End Sub 
End Class 

And here is how a test for the ThrowsException method will look like:

[TestMethod] 
[ExpectedException(typeof(NotImplementedException))] 
public void PrivateAccessor_CallMethod_ThrowsException() 
{ 
    var instance = new PrivateAccessor(new Foo()); 
    instance.RethrowOriginalOnCallMethod = true; 
    instance.CallMethod("ThrowsException"); 
} 
<TestMethod> 
<ExpectedException(GetType(NotImplementedException))> 
Public Sub PrivateAccessor_CallMethod_ThrowsException() 
    Dim instance = New PrivateAccessor(New Foo()) 
    instance.RethrowOriginalOnCallMethod = True 
    instance.CallMethod("ThrowsException") 
End Sub 

See Also

In this article
Not finding the help you need? Improve this article