c# - 单元测试私有(private)代码

标签 c# testing methods tdd private

<分区>

我目前正在使用 C# 进行开发 - 以下是一些背景信息: 我们用我们的客户端应用程序实现 MVP,并且我们有一个圈规则,该规则规定任何方法的圈复杂度都不应大于 5。 这导致了很多小的私有(private)方法,这些方法通常只负责一件事。

我的问题是关于对类进行单元测试的:

通过公共(public)方法测试私有(private)实现没问题......我在实现这个方面没有问题。

但是……下面的情况呢:

Example 1. Handle the result of an async data retrival request (The callback method shouldn't be public purely for testing)

Example 2. An event handler which does an operation (such as update a View label's text - silly example I know...)

Example 3. You are using a third party framework which allows you to extend by overriding protected virtual methods (the path from the public methods to these virtual methods are generally treated as black box programming and will have all sorts of dependancies that the framework provides that you don't want to know about)

以上示例在我看来并不是设计不佳的结果。 它们似乎也不是移动到单独的类进行隔离测试的候选者,因为这样的方法将失去它们的上下文。

有没有人对此有任何想法?

干杯, 杰森

编辑: 我认为我在最初的问题中不够清楚——我可以使用访问器测试私有(private)方法并使用 TypeMock 模拟调用/方法。那不是问题所在。问题是测试不需要公开或不能公开的东西。

我不想为了测试而公开代码,因为它会引入安全漏洞(只发布一个接口(interface)来隐藏它不是一种选择,因为任何人都可以将对象转换回其原始类型并获得访问权限做一些我不希望他们做的事情)

重构到另一个类进行测试的代码很好——但可能会丢失上下文。我一直认为拥有可以包含一堆没有特定上下文的代码的“助手”类是不好的做法 - (在这里考虑 SRP)。我真的认为这也不适用于事件处理程序。

我很高兴被证明是错误的——我只是不确定如何测试这个功能!我一直认为,如果它可以损坏或更改 - 测试它。

干杯,杰森

最佳答案

正如 Chris 所说,仅对公共(public)方法进行单元测试是标准做法。这是因为,作为该对象的消费者,您只关心对您公开可用的内容。而且,从理论上讲,对边缘案例进行适当的单元测试将充分发挥它们拥有的所有私有(private)方法依赖性。

话虽这么说,但我发现有几次直接针对私有(private)方法编写单元测试非常有用,并且最简洁地通过单元测试解释了一些更复杂的场景或边缘情况可能是遇到了。

如果是这种情况,您仍然可以使用反射调用私有(private)方法。

MyClass obj = new MyClass();
MethodInfo methodInfo = obj.GetType().GetMethod("MethodName", BindingFlags.Instance | BindingFlags.NonPublic);
object result = methodInfo.Invoke(obj, new object[] { "asdf", 1, 2 });
// assert your expected result against the one above

关于c# - 单元测试私有(private)代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1506427/

相关文章:

c# - 使用目标 :module switch 编译代码

javascript - 测试浏览器扩展

c# - 将小数格式化为两位或整数

c# - 如何在使用 OWIN 的 WebApi 项目上启用 Application Insights 服务器遥测?

javascript - 检查是否有效

ruby - 阻止或重定向请求到 Selenium 中的特定路径或域

c# - 如何处理重复的参数声明?

java - 增加 Java 中用户输入的百分比

python:当类属性、实例属性和方法都同名时会发生什么?

c# - 使用 Mock、Repository 和 UnitOfWork C# UnitTesting 测试 BLL