Search code examples
c#unit-testingmockingrhino-mocks

How to mock instance methods called by the tested method so you test only one thing?


Imagine that I have the following class:

class ToTest : IToTest
{
    public string MethodA()
    {
        return "Test";
    }

    public int MethodB()
    {
        returns a random number;
    }

    public string MethodC()
    {
        return this.MethodA + " " + this.MethodB.ToString();
    }
}

I'm testing now MethodC so I understand that I should mock MethodA and MethodB of my current instance so I only test MethodC validity right?

I'm using Rhino and I did the following:

ToTest testedObject = new ToTest();

testedObject.Expect(t => t.MethodA).Returns("AString");
testedObject.Expect(t => t.MethodB).Returns(1324");

Assert.AreEqual("AString 1324", testedObject.MethodC());

But I get an error correctly saying that the testedObject is not a Mock.

Is the approach right? How should I proceeed?


Solution

  • No, please do not write test cases like this. Unit tests are not about "testing just one thing", they are all about ensuring that each test is a unit, ie it has no influence on any other test.

    All your tests should be interested in is the public API of your class. Do not test internals or private methods, they are part of the inner workings of your class, and do not try to mock parts of your class in order to test other parts. Your test of MethodC must indirectly test MethodA and MethodB too, otherwise your test is meaningless.

    For anyone interested in an excellent talk on how to write good unit tests, I'd recommend setting aside an hour and watching the 'Ian Cooper: TDD, where did it all go wrong' video from NDC 2013.