Unit test protected method in C# using Moq

前端 未结 3 1887
闹比i
闹比i 2021-02-18 14:48

It came to my attention lately that you can unit test abstract base classes using Moq rather than creating a dummy class in test that implements the abstract base class. See How

3条回答
  •  有刺的猬
    2021-02-18 15:21

    For starters, there's no point in unit testing an abstract method. There's no implementation! You may want to unit test an impure abstract class, verifying that the abstract method was called:

    [Test]
    public void Do_WhenCalled_CallsMyAbstractMethod()
    {
        var sutMock = new Mock() { CallBase = true };
        sutMock.Object.Do();
        sutMock.Verify(x => x.MyAbstractMethod());
    }
    
    public abstract class MyAbstractClass
    {
        public void Do()
        {
            MyAbstractMethod();
        }
    
        public abstract void MyAbstractMethod();
    }
    

    Note that I set CallBase to turn this into a partial mock, in case Do was virtual. Otherwise Moq would have replaced the implementation of the Do method.

    Using Protected() you could verify that a protected method was called in a similar manner.

    When you create a mock with Moq or another library, the whole point is overriding implementation. Testing a protected method involves exposing existing implementation. That's not what Moq is designed to do. Protected() just gives you access (presumably through reflection, since it's string-based) to override protected members.

    Either write a test descendant class with a method that calls your protected method, or use reflection in the unit test to call the protected method.

    Or, better yet, don't test protected methods directly.

提交回复
热议问题