Home > Back-end >  Moq parent method being called in child class
Moq parent method being called in child class

Time:01-07

I have a base class with a protected method that's being called in a public method in the child class I want to test. I'm failing to find a way to moq the base protected method for easier testing in child class.

class MyBaseClass
{
    protected virtual bool MyMethod(int number)
    {
        return number == 1;
    }   
}

class MyChildClass : MyBaseClass
{
    public bool DoSomething(int number)
    {
        return MyMethod(number);
    }
}

[TestFixture]
class MyChildClassTests
{
    [Test]
    public void Expected_Returns_False_WhenPassed_1()
    {
        var myChildClass = new MyChildClass();

        // How do I mock MyMethod used in myBaseClass here?
        // var mock = new Mock<MyBaseClass>();
        // mock.Protected().Setup<bool>("MyMethod", ItExpr.IsAny<int>()).Returns(false);
        
        // The above mock is correct, but it's in a different instance object than myBaseClass

        var result = myChildClass.DoSomething();

        Assert.AreEqual(false, result);
    }
}

I can't change the classes to have a better architecture and I must do the best I can to implement unit test for DoSomething(), what I did so far is mock and prepare all the data that method uses, but since it's in another class I'd love my MyChildClassTests to not do all that and just limit to test DoSomething().

I've read about partial mocking and a whole lot of other questions and answers and I can't get it to work right.

I appreciate any suggestions!

CodePudding user response:

class MyChildClassTests
{
    [Test]
    public void Expected_Returns_False_WhenPassed_1()
    {
        var myChildClass = new FakeChildClass();
        
        var result = myChildClass.DoSomething(1);

        Assert.AreEqual(false, result);
    }
}

public class FakeChildClass: MyChildClass
{
    protected override bool MyMethod(int number)
    {
        return number == 1;
    }
}

CodePudding user response:

First of all, ensure your classes are public.

Moq will complain about not being able to proxy into them if they're not.

public class MyBaseClass
{
    public virtual bool MyMethod(int number)
    {
        return number == 1;
    }   
}

public class MyChildClass : MyBaseClass
{
    public bool DoSomething(int number)
    {
        return MyMethod(number);
    }
}

Next, make your base class method public. You won't be able to set it up unless you do.

After that, create a mock of the child object and mock the parent method.

var mockChild = new Mock<MyChildClass>(){CallBase = true};
            mockChild.Setup(x => x.MyMethod(It.IsAny<int>())).Returns(false);

Pull your result.... result will return false even though the actual implementation would have returned true with 1 as a parameter.

var result = mockChild.Object.DoSomething(1);

When calling the DoSomething method, you'll actually enter the real implementation of that (put a breakpoint on if you don't believe me!) - but the mocked version of MyMethod will kick in.

  •  Tags:  
  • Related