Thursday, 17 January 2019

Implementing mocking objects with Moq when constructor has parameters

Very often we faced with the situation, we have to mock object, that have no interface.

The best thing to do would be right click on your class and choose Extract interface. But in case it isn't possible let's start work with existing class. So, usually it doesn't cause any problems, we can do it easy:
 
    public class TestConstructor { ...
    }

    [Test]
    public void SomeTest() {
        var t = new Mock<TestConstructor>();
    }

The only problem with Mocking Concrete types is that Moq would need a public default constructor(with no parameters).

Let's imagine that we have class with public constructor with parameters:
 
    public class TestConstructor {
        public TestConstructor(string val)
        {
            Value = val;
        }

        public string Value { get; }
    }

    [Test]
    public void SomeTest() {
        var t = new Mock<TestConstructor>();
        // the next raw throw an exception
        var tt = t.Object.Value; // exception!
    }

In case we try this code, will get an Exception, because we can't create an instance of object in this way of class, that doesn't have public constructor without parameters.
Well  we need to create the Moq with constructor arg specification:
 
    public class TestConstructor {
        public TestConstructor(string val)
        {
            Value = val;
        }

        public string Value { get; }
    }

    [Test]
    public void SomeTest() {
        var t = new Mock<TestConstructor>(MockBehavior.Strict, new object[] { "data" });
        // now, the next raw is OK
        var tt = t.Object.Value; // tt = "data"
    }

Of cause we can simplify mocking using short syntax:
 
    var t = new Mock<TestConstructor>("data");

That's all!

No comments:

Post a Comment