2

I am trying to learn how to use Moq to do unit testing with C#. I setup a simple class, BasicMath that has a function int Multiply(int a, int b), the body just returns a * b. I have another class called AdvancedMath which has a function 'int Square(int a)', the body calls Multiply(a,a) and returns the result.

I am trying to write a simple test for AdvancedMath.Square that will assert that BasicMath.Multiply is called with the correct values. I understand that you cannot do this with ordinary public function so I made the functions virtual, but I am still having trouble. Can someone explain to me how this is done? Neither class has any constructor other than the default empty constructor.

Here is my attempt:

class test_Advanced_Functions
{
    [Test]
    public void test_SquareFunction_Should_return_correct_result()
    {
        // Arrange
        Mock<BasicFunctions> mock = new Mock<BasicFunctions>();
        AdvancedFunctions af = new AdvancedFunctions();

        // Act
        int result = af.Square(5);

        //Assert
        mock.Verify(d => d.Multiply(5, 5), Times.Exactly(1));
    }
PICyourBrain
  • 9,976
  • 26
  • 91
  • 136
  • possible duplicate of [Using Moq to determine if a method is called](http://stackoverflow.com/questions/347818/using-moq-to-determine-if-a-method-is-called) – StriplingWarrior May 07 '12 at 15:11
  • @StriplingWarrior - The difference is that in question referenced the method under test takes the other class as one of it's parameters. It should be possible to assert a function is called without forcing that you pass the object in as a parameter... right? – PICyourBrain May 07 '12 at 15:30

2 Answers2

3

Assuming AdvancedMath derives from BasicMath then you can test that with Moq when Multiply is virtual:

var mock = new Mock<AdvancedMath>();
mock.Setup(m => m.Multiply(2, 2)).Returns(4);
mock.Object.Square(2);
mock.VerifyAll();

If you use BasicMath within AdvancedMath (ie. if Multiply is static and is invoked directly from Square), then testing such interaction is not possible with Moq. To see why, see this question.

However, doing behavior based verification in such simple case doesn't seem right. You need to answer yourself a question: "what do I want to test?". That Square works or that it calls some methods? This test (what you plan to do now), only delegates responsibility to Multiply, assuming it works. Your Square implementation might change in multiple ways (as in, not using Multiply) and it will break your test - it shouldn't.

Community
  • 1
  • 1
k.m
  • 30,794
  • 10
  • 62
  • 86
1

Moq cannot modify behavior of instances that it has not created.

You should write your classes to be unit-testable by practicing dependency injection. Since AdvancedFunctions apparently depends on BasicFunctions, it should have a BasicFunctions passed in as a constructor argument, rather than newing one up on its own.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315