使用Moq在C#中进行单元测试保护的方法 [英] Unit test protected method in C# using Moq

查看:112
本文介绍了使用Moq在C#中进行单元测试保护的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近引起我注意的是,您可以使用Moq对抽象基类进行单元测试,而不是在实现抽象基类的测试中创建虚拟类.参见如何使用最小订量在抽象类中测试具体方法?例如您可以这样做:

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 to use moq to test a concrete method in an abstract class? E.g. you can do:

public abstract class MyAbstractClass 
{
    public virtual void MyMethod()
    {
        // ...    
    }
}

[Test]
public void MyMethodTest()
{
    // Arrange            
    Mock<MyAbstractClass> mock = new Mock<MyAbstractClass>() { CallBase = true };

    // Act
    mock.Object.MyMethod();

    // Assert
    // ... 
}

现在,我想知道是否有类似的技术可以让我测试受保护的成员而不必创建包装类. IE.您如何测试此方法:

Now I was wondering if there was a similar technique to allow me to test protected members without having to create a wrapper class. I.e. how do you test this method:

public class MyClassWithProtectedMethod
{
    protected void MyProtectedMethod()
    {

    }
}

我知道Moq.Protected名称空间,但是据我所知,它仅允许您设置期望值,例如.

I'm aware of the Moq.Protected namespace, however as far as I can see it only allows you to setup expectations with e.g.

mock.Protected().Setup("MyProtectedMethod").Verifiable();

我也知道,这里显而易见的答案是不测试受保护的方法,仅测试公共方法",但这是另一个争论!我只想知道使用Moq能否做到这一点.

I'm also aware that the obvious answer here is "don't test protected methods, only test public methods", however that's another debate! I just want to know if this is possible using Moq.

更新:以下是我正常测试的方式:

Update: below is how I would test this normally:

public class MyClassWithProtectedMethodTester : MyClassWithProtectedMethod
{
    public void MyProtectedMethod()
    {
        base.MyProtectedMethod();
    }
}

谢谢.

推荐答案

对于初学者来说,对抽象方法进行单元测试毫无意义.没有实现!您可能需要对一个不纯的抽象类进行单元测试,以验证抽象方法是否被调用:

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<MyAbstractClass>() { CallBase = true };
    sutMock.Object.Do();
    sutMock.Verify(x => x.MyAbstractMethod());
}

public abstract class MyAbstractClass
{
    public void Do()
    {
        MyAbstractMethod();
    }

    public abstract void MyAbstractMethod();
}

请注意,如果Do是虚拟的,我将CallBase设置为将其转换为部分模拟.否则Moq会替换Do方法的实现.

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.

使用Protected(),您可以验证是否以类似的方式调用了受保护的方法.

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

使用Moq或其他库创建模拟时,最重要的是重写实现.测试受保护的方法涉及公开现有的实现. Moq并不是要这样做的. Protected()仅使您可以访问(大概是通过反射,因为它是基于字符串的)以覆盖受保护的成员.

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.

这篇关于使用Moq在C#中进行单元测试保护的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆