Posts Tagged ‘patterns’

Unit Testing: Allowing Access to Internal Members of Types in Another Assembly

February 5, 2008

Create a Friend Assembly by adding [assembly: InternalsVisibleTo(“Other.Assembly”)] in AssemblyInfo.cs to allow that Other.Assembly access to this assembly’s types’ internal members.

Good object-oriented design involves guarding access to members of types appropriately. Part of a domain object’s state may only be mutated by other types in the same assembly (for example during creation). Those members will be protected with the internal keyword (in .Net).

This causes issues when trying to achieve 100% coverage during testing. Unit tests are usually located in another assembly (even if the namespace is shared for simplicity). That unit test assembly will not have access to the internal members and therefore some important states of a domain object cannot be tested. Assume you have the following domain object assembly:

// assembly Acme.Model
namespace Acme.Model
{
  public class Stuff
  {
    private List _data = new List();
    public ICollection Data { get { _data; } }
    internal void AddData(string data)
    {
       _data.Add(data);
    }
  }
}

We want to test the above class with 100% coverage, meaning we have to get Data added to it. The associated unit test would pretty much look like this, but not compile, because of the inaccessible internal member:

// assembly Acme.UnitTests.Model
namespace Acme.Model
{
  [TestFixture]
  public class TestStuff
  {
    [Test]
    public void TestData()
    {
       Stuff stuff = new Stuff();
       stuff.AddData("data"); // this is not going to compile
       Assert.AreEqual(1, stuff.Data.Count);
    }
  }
}

Declaring a Friend Assembly is a very quick and simple fix for this problem. In Acme.Model’s AssemblyInfo.cs, just add the following line at the end:

[assembly: InternalsVisibleTo("Acme.UnitTests.Model")]

For more on that topic, see Friend Assemblies on MSDN.

Advertisements