c# - 抽象类的单元测试保护方法

标签 c# .net reflection nunit abstract-class

我正在尝试编写单元测试来测试抽象类中的 protected 方法。我尝试编写一个从抽象类继承的测试类,但是当我实例化测试类时,基本抽象类尝试连接到 Oracle 数据库并失败,这不允许我测试我感兴趣的 protected 方法in.抽象类不可修改。

如何直接对这个抽象类中的 protected 方法进行单元测试?

这是我尝试过的反射的片段。

Type type = typeof(AbstractClass);
BindingFlags eFlags = BindingFlags.Instance | BindingFlags.NonPublic;
MethodInfo myMethod = type.GetMethod("ProtectedMethod", eFlags);
object[] arguments = new object[] { _myDs };
myMethod.Invoke(type, arguments);
_myDs = (DataSet)arguments[0];

最佳答案

这是可行的,但请注意您的代码可能存在几个严重的问题:

  • 构造函数不应执行任何业务逻辑。
  • 你的抽象类不应该知道数据库类型(依赖倒置原则)。
  • 你的抽象类有更多职责吗?如果是,将它们移至单独的类/项目(单一职责原则)。
  • 您不应该对非公共(public) API 进行单元测试。

这是一个食谱:

  • 首先,创建抽象类的假实例。
  • 然后,调用 FormatterServices.GetUninitializedObject 获取类的实例,而无需调用构造函数。
  • 之后,您可以使用反射调用ProtectedMethod

这样,您就可以测试 ProtectedMethod:

  • 不调用构造函数。
  • 不修改抽象类。

这是一个示例代码:

class AbstractClassFake : AbstractClass { }

[Test]
public void Test()
{
    // Arrange:
    var abstractClassFake = (AbstractClassFake)FormatterServices
        .GetUninitializedObject(typeof(AbstractClassFake));

    MethodInfo method = abstractClassFake.GetType()
        .GetMethod("ProtectedMethod",
            BindingFlags.Instance | BindingFlags.NonPublic);

    object[] arguments = new object[] { myDs };

    // Act:
    object val = method.Invoke(abstractClassFake, new[] { myDs });

    // Assert:
    // TODO: Your assertion here
}

关于c# - 抽象类的单元测试保护方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20504378/

相关文章:

.net - 将扁平化数据源转换为分层数据源

c# - 使用 PropertyInfo.GetValue()

c# - 如何使用 Android Xamarin 从 WebApi 获取数据?

.net - 我可以在 IE8 中显示 windows 用户控件吗

c# - default(CancellationToken) 如何有相应的 CancellationTokenSource

actionscript-3 - AS3 从静态方法中获取当前类名

c# - 反射有多慢

c# - System.IO 中没有 "Directory"或 "File"

c# - 如何创建通用获取自定义 WebConfig 部分扩展方法

c# - 如何内联我的内部函数?