Create mock of class without calling original class constructor

Viewed 108

Say i have library with this code (that canot be changed)

namespace Library.Namespace;

public interface ISomething { }

internal class Something : ISomething { 
    public Something(...) {
        ...
    }
}

public class Anything {
    private Something _Something;

    public Anything (ISomething something) {
        _Something = (Something) something;
        ...
    }
}

and i want to create mock of Anything class:

public MockAnything : Mock<Anything> {
    public MockSomething Something { get; }

    public MockAnything() 
        : this(new MockSomething()) { 
    }

    public MockAnything(MockSomething something) 
        : base(something.Object) {
        Something = something;
    }
}

public MockSomething : Mock<ISomething> {
}

everythig good so far (aka compiller is happy), but at runtime im getting exception when calling:

var mock = new MockAnything();

var object = mock.Object; // <-- exception here

System.InvalidCastException 
Unable to cast object of type 'Castle.Proxies.ISomethingProxy' to type 'Library.Namespace.Something'.
  at Library.Namespace.Something..ctor(ISomething something)
  at Castle.Proxies.AnythingProxy..ctor(IInterceptor[] , ISomething something)

any idea how to correctly mock class, that uses direct cast in constructor?

1 Answers

When using Moq, the best and easiest way is to create mocks based on interfaces. Unfortunately, you cannot change the library and add an interface there or get rid of the cast (which would be best anyway).

From a design perspective, I'd recommend to create a wrapper around the library code that you cannot change. In addition, you create an interface (let's call it IAnything) that contains the methods that you want to use. Instead of using Anything directly in your code, you'd inject IAnthing into your code. The following code outlines the necessary classes:

public IInterface IAnything
{
  // Members of the original Anything class that you want to use in your code
}

public class AnythingWrapper : IAnything
{
  private readonly Anything _anything;

  public AnythingWrapper(Anything anything) 
  {
    _anything = anything;
  }

  // IAnything implementation
}

While this might seem like a bit of extra work, it usually is done with some paste-and-copy. In addition, you create a layer of abstraction between your code and the library code. If the library changes in the future, you could be able to apply the changes in your wrapper class without changing the interface as such.

As soon as you have created the interface, you can easily create a mock, e.g.:

var mockAnything = new Mock<IAnything>();
Related