Mocking a private field

Samuel Heaney picture Samuel Heaney · Jun 26, 2012 · Viewed 12.1k times · Source

I know a similar question has been asked but I have not found a clear solution. I'm trying to mock a private field from a large class. The private field gets instantiated in some earlier method and I'm trying to unit test a latter method which references the field.

So I have an earlier method in my class:

public bool validateAll(ref DataEntry[] oEntries, string sMediaPlanId, ITemplateGenerator oTempGen)
{
  ...
  // private field that I am trying to mock
  this._sMediaPlanObjective = (MPWrapper.Instance).getMediaPlanObjective(sMediaPlanId);
  ...
}

And I'm trying to Unit test a method that references the private field:

public bool validateFlightObjective(ref MPDataEntry oEntry)
{
  ...
  string entryFlightObjective = oEntry.getFlightObjective();
  string mediaPlanObjective = this._sMediaPlanObjective;

  if (entryFlightObjective != mediaPlanObjective)
  {
    return false;
  }
  ...

  return true;      
}

Given that I have a large class and this is just one method I want to test, is there a possible way to just mock this private field? Am I missing something basic or should I consider some other approach?

Answer

k.m picture k.m · Jun 26, 2012

You can't mock anything that's private, static, or essentially - non overridable (this comes as a free mocking libraries limitation).

What you usually do in such situations (when it appears that private member has to be tested), is extracting your private member to a separate class and inject it to tested class as a dependency.

In your case, you actually need to extract code that creates _sMediaPlanObjective, which is this line:

this._sMediaPlanObjective =
    (MPWrapper.Instance).getMediaPlanObjective(sMediaPlanId);

Object that provides getMediaPlanObjective method should be injected to your tested class. If you do so, you can simply mock that object and tell it to return mocked version of _sMediaPlanObjective.