moq/labs

Allow Access to Protected Class Members

Closed this issue ยท 0 comments

Hi folks! ๐Ÿ‘‹

Summary

As far as I know, Moq doesn't provide direct access to protected class members. You can call ProtectedExtension.Protected<T>(Mock<T> mock) to setup the mock's protected members, but you can't directly get/set protected properties/fields, and you can't directly call protected methods. This can make it difficult to mock a base class and test the base class's functionality.

Example

Suppose that you have the following:

public abstract class BaseClass {
    protected string _commonField;

    protected BaseClass() {
        _commonField = GetStringWithId("SomeId");
    }

    public string GetStringWithId(string id) {
        // Returns string with given ID.
    }
}

public class FirstImplementation : BaseClass  {
    public FirstImplementation() : base() { }

    public void SomeMethod() {
        // Uses _commonField.
    }
}

public class SecondImplementation : BaseClass {
    public SecondImplementation() : base() { }

    public void AnotherMethod() {
        // Uses _commonField
    }
}

Since _commonField is used by implementors, I would argue that you should create a unit test for the _commonField property. Ideally, you would do this by using the partial mock feature with BaseClass. This unit test would validate that _commonField is getting set correctly in the constructor; that way you can validate that the correct value is getting provided to FirstImplementation and SecondImplementation.

The concern is that Moq doesn't provide direct access to the _commonField field, so you can't verify that it is getting set correctly. Instead, you either have to (a) create your own mock or (b) use reflection.