Published on, Time to read
🕒 2 min read

How to test a class that has constructor impossible to mock?

How to test a class that has constructor impossible to mock?

In some cases, there are classes with constructors that are impossible to mock with proxy-based mocking frameworks (such as Moq, FakeItEasy, NSubstitute, etc). In this article, I will present how to create a test for class that is impossible to mock.

Some constructors might be difficult or even impossible to mock because of:

  • There's limited access to the class, because of the access level (private, internal, etc.)
  • The constructor has a dependency that is difficult to create or mock
  • Or, it has a tree of dependencies that are difficult to create or mock

Consider the following example:

public class ClassWithDifficultCtorToMock
{
    private ClassWithDifficultCtorToMock(string dep1)
    {
        Dep1 = dep1;
    }

    public string Dep1 { get; set; }
}

In the above case, we cannot easily mock the class ClassWithDifficultCtorToMock because it has a private constructor.

Solution? What we can do is to create a class using the FormatterServices.GetUninitializedObject. This reflection technique by-passes all the logic in the constructor and creates an object with all the fields set to their default values. We can use it like this:

FormatterServices.GetUninitializedObject(typeof(ClassWithDifficultCtorToMock))

That's a little hacky, but it works and is very useful in unit testing scenarios.

Now, we can build our test for the difficult class:

[Test]
public void demonstrate_ctor_creation()
{
    var cls = Create();
    cls.Dep1 = "test";

    cls.Dep1.Should().Be("test");
}

private static ClassWithDifficultCtorToMock Create() =>
    (ClassWithDifficultCtorToMock)FormatterServices
        .GetUninitializedObject(typeof(ClassWithDifficultCtorToMock));