Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to unit test methods which depend on a private field?

I just started writing some tests for a new project and encountered the following "problem":

I mocked the dependent INotifyVariableChangedService and OpcClient to test my OpcService:

private readonly OpcUaClient _client;
        private readonly INotifyVariableChangedService _notifyVariableChangedService;
        private readonly ushort _symbolicsIndex;

        public OpcService(INotifyVariableChangedService notifyVariableChangedService)
        {
            this._notifyVariableChangedService = notifyVariableChangedService;

            this._client = new OpcUaClient("", "");

            _symbolicsIndex = _client.GetSymbolicsNameSpaceId();
        }

Here you can see, that i get the _symbolicsIndex, which i only have to do one time. Consequently i’m persisting it in a field and reusing it whenever i need it again.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This brought up a problem when testing a method like this one, because it depends on the value in this field:

public async Task<KeyValuePair<string, object>> GetVariableValue(string nodeIdentifier, string variableName)
        {
            var variableValue = await this._client.GetValue(nodeIdentifier, variableName, _symbolicsIndex);

            return new KeyValuePair<string, object>(variableName, variableValue.Value);
        }

Of course i could refactor this and get the _symbolicsIndex everytime in my controller, but that does not seem like a clean solution at all.

Is there a way to "mock" this field ? Should i even be doing that at all or should i refactor it and expose a method, which sets the _symbolicsIndex in my service explicitly, instead of setting it in the constructor ?

Any help would be greatly appreciated.

>Solution :

I don’t think you can mock a private field without using reflection, but I would suggest that you also have the client injected rather than instantiating it in the constructor.

You said the client is already a mocked object, so you could fake the GetSymbolicsNameSpaceId() method and return the desired mocked value, which is then set to the private field when the client is passed to the constructor.

This could then look something like this (assumed FakeItEasy as the mocking libary)

private readonly OpcUaClient _client;
private readonly INotifyVariableChangedService _notifyVariableChangedService;
private readonly ushort _symbolicsIndex;

public OpcService(INotifyVariableChangedService notifyVariableChangedService, OpcUaClient client)
{
    this._notifyVariableChangedService = notifyVariableChangedService;
    this._client = client;

    _symbolicsIndex = _client.GetSymbolicsNameSpaceId();
}

Test:

_notifyVariableChangedService = A.Fake<INotifyVariableChangedService>();
_client = A.Fake<OpcUaClient>();

A.CallTo(() => _client.GetSymbolicsNameSpaceId()).Returns(1);

_testee = new OpcService(_notifyVariableChangedService, _client);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading