docs/TestAccessor Pattern.md
TestAccessor PatternThe TestAccessor pattern allows production code to expose internal functionality for test purposes without making the internal functionality available to other production code. The pattern has two primary components:
TestAccessor type, which contains the functionality available only for testingGetTestAccessor() method, which returns an instance of TestAccessorThe pattern relies on enforcement of a simple rule that no production code is allowed to call a GetTestAccessor() method. This is enforceable either through code reviews or through an analyzer. This pattern has many advantages over alternatives:
internal instead of private) for the purpose of testingTestAccessor type are intended only for use in test codeTestAccessor TypeThe TestAccessor type is typically defined as a nested structure. In the following example, the SomeProductionType.TestAccessor.PrivateStateData property allows test code to read and write the value of the private field SomeProductionType._privateStateData without exposing the _privateStateData field to other production code.
internal class SomeProductionType
{
private int _privateStateData;
internal readonly struct TestAccessor
{
private readonly SomeProductionType _instance;
internal TestAccessor(SomeProductionType instance)
{
_instance = instance;
}
internal ref int PrivateStateData => ref _instance._privateStateData;
}
}
GetTestAccessor() MethodThe GetTestAccessor() method is always defined as follows:
internal TestAccessor GetTestAccessor()
=> new TestAccessor(this);