Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq and constructors - testing initialisation behaviour

I'd like to be able to test a class initialises correctly using Moq:

class ClassToTest
{
    public ClassToTest()
    {
        Method1(@"C:\myfile.dat")
    }
 
    public virtual void Method1(string filename)
    {
        // mock this method
        File.Create(filename);
    }
}

I thought I'd be able to use the CallBase property to create a testable version of the class, then use .Setup() to ensure Method1() does not execute any code.

However, creating the Mock<ClassToTest>() doesn't call the constructor, and if it did it'd be too late to do the Setup()!

If this is impossible, what is the best way round the problem whilst ensuring that the constructor behaves correctly?

EDIT: To make it clearer, I've added a parameter to Method1() to take a filename and added some behaviour. The test I'd like to write would be a working version of the following:

[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
    var mockClass = new Mock<ClassToTest>() { CallBase = true };
    mockClass.Setup(x => x.Method1(It.IsAny<string>());

    mockClass.Verify(x => x.Method1(@"C:\myfile.dat"));
}
like image 646
g t Avatar asked Sep 08 '10 12:09

g t


People also ask

What is Moq in testing?

Moq is a mocking framework for C#/. NET. It is used in unit testing to isolate your class under test from its dependencies and ensure that the proper methods on the dependent objects are being called.

How do you construct a unit test of a constructor?

To test that a constructor does its job (of making the class invariant true), you have to first use the constructor in creating a new object and then test that every field of the object has the correct value. Yes, you need need an assertEquals call for each field.

Is Moq a testing framework?

The Moq framework is an open source unit testing framework that works very well with . NET code and Phil shows us how to use it.

Should we write unit test for constructors?

Not unless you're writing a compiler, because you would only be testing that the compiler could generate code to do assignments, which is normally pointless.


1 Answers

Way down inside of Moq.Mock (actually inside the CastleProxyFactory that Moq uses)

mockClass.Object

will call the constructor by way of Activator.CreateInstance()

So your test would look something like

[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
    Mock<ClassToTest> mockClass = new Mock<ClassToTest>();
    mockClass.Setup(x => x.Method1(It.IsAny<string>());

    var o = mockClass.Object;

    mockClass.Verify(x => x.Method1(@"C:\myfile.dat"));
}
like image 111
Matt Mills Avatar answered Oct 26 '22 13:10

Matt Mills