This is a migrated thread and some comments may be shown as answers.

Mock Private Sub-Class

3 Answers 131 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Robert
Top achievements
Rank 1
Robert asked on 11 Nov 2013, 10:28 PM
I have a protected static sub-class that I use for DataAccess.  Its locked down so that no other part of the application/code can access or is aware of the database.  I'm doing the unit tests for the host class and I need to Mock the protected static sub-class so that there are no database calls in the unit test.  How do I do that and check occurances? Thanks.
public partial class Manager
{
    protected static class DataAccess
    {
        public static void CallMyStoredProcedure()
        { }
    }
}

3 Answers, 1 is accepted

Sort by
0
Kaloyan
Telerik team
answered on 12 Nov 2013, 12:12 PM
Hi Robert,

Thank you for bringing this matter. It is indeed tricky scenario. However, if you are able to get the type of the static class, you will be able to mock it.

In order to test the mock, I added a public method to call the static one, like this:
public partial class Manager
{
    protected static class DataAccess
    {
        public static void CallMyStoredProcedure()
        {
            throw new NotImplementedException();
        }
    }
 
    public void CallInnerMethod()
    {
        Manager.DataAccess.CallMyStoredProcedure();
    }
}

Having the above, the following test behaved as expected:
[TestMethod]
public void ShouldMockProtectedStatic()
{
    // Arrange
    var stringToLookFor = "ProtectedAss.Manager+DataAccess, " + typeof(Manager).Assembly.FullName;
    Type dataAccessType = Type.GetType(stringToLookFor, true);
 
    Mock.NonPublic.Arrange(dataAccessType, "CallMyStoredProcedure").DoNothing().OccursOnce();
 
    // Act
    var managerInst = new Manager();
    managerInst.CallInnerMethod();   
}
First, I am getting the type of the protected static class (DataAccess). Then, I arrange that CallMyStoredProcedure should do nothing when called and in the same time it must occur exactly once during the test execution. Calling the CallInnerMethod() verifies my test. With this approach you should be able to mock all of the needed DataAccess' members.

Another thing you can do is to use the Mock.SetupStatic(). It will automatically mock the whole DataAccess class and its members will be arranged to do nothing. Then you will only need to assert on the expected members. The next example explains this in more details:
[TestMethod]
public void ShouldMockProtectedStatic()
{
    // Arrange
    var stringToLookFor = "ProtectedAss.Manager+DataAccess, " + typeof(Manager).Assembly.FullName;
    Type dataAccessType = Type.GetType(stringToLookFor, true);
 
    Mock.SetupStatic(dataAccessType);
 
    // Act
    var managerInst = new Manager();
    managerInst.CallInnerMethod();
 
    // Assert
    Mock.NonPublic.Assert(dataAccessType, "CallMyStoredProcedure", Occurs.Once());
}

I hope this helps. Please, let me know if I can assist you further.

Regards,
Kaloyan
Telerik
Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
0
Robert
Top achievements
Rank 1
answered on 12 Nov 2013, 02:37 PM
Hey, Thanks for the detailed answer, it worked perfectly.  You were right to added the public call method, I mistakenly left it off my example code.
Just for someone else reading, "ProtectedAss" is the full namespace of your example class.
0
Kaloyan
Telerik team
answered on 12 Nov 2013, 04:19 PM
Hi again Robert,

I am glad this solved the issue.

Please, do not hesitate to contact us again. Have a nice day and happy mocking :).

Regards,
Kaloyan
Telerik
Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
Tags
General Discussions
Asked by
Robert
Top achievements
Rank 1
Answers by
Kaloyan
Telerik team
Robert
Top achievements
Rank 1
Share this question
or