单元测试私有代码

14 浏览
0 Comments

单元测试私有代码

我目前正在使用C#进行开发 - 这里是一些背景信息:

我们在客户应用程序中实现MVP模式,并且我们有一个循环复杂度规则,规定没有一个方法的循环复杂度可以超过5。

这导致了很多小的私有方法,这些方法通常负责一件事情。

我的问题是关于测试一个类:

通过公共方法测试私有实现是没有问题的...我没有问题来实现这个。

但是...以下情况怎么办:

例1:处理异步数据检索请求的结果(回调方法不应该为了测试而公开)

例2:一个事件处理程序执行某个操作(例如更新视图标签的文本 - 我知道这个例子有点傻)

例3:你正在使用一个第三方框架,允许通过重写受保护的虚拟方法来扩展(从公共方法到这些虚拟方法的路径通常被视为黑盒编程,并且会有各种框架提供的你不想知道的依赖项)

上述例子对我来说并不是设计不良的结果。

它们也不是将其移动到一个单独的类中进行隔离测试的候选方法,因为这样的方法将失去它们的上下文。

有人对此有什么想法吗?

谢谢,

Jason

编辑:

我觉得我在最初的问题中没有表达清楚 - 我可以使用访问器测试私有方法,并使用TypeMock模拟调用/方法。这不是问题。问题是测试不需要公开的东西,或者不能公开的东西。

我不想为了测试而将代码公开,因为这可能会引入安全漏洞(只发布一个接口来隐藏这一点不是一个选择,因为任何人都可以将对象转换回其原始类型并访问我不想让他们访问的内容)

代码被重构到另一个类进行测试是可以的 - 但可能会失去上下文。我一直认为“helper”类可能包含没有特定上下文的大量代码是不好的实践(考虑SRP)。我真的不认为这对事件处理程序有效。

我很乐意被证明是错误的 - 我只是不确定如何测试这个功能!我一直认为,如果它可能出错或可能被更改 - 那就进行测试。

谢谢,Jason

0
0 Comments

私有代码的单元测试是一种常见的测试方法,但有时会遇到一些问题。本文将讨论私有代码单元测试的问题、出现原因以及解决方法。

问题出现的原因是私有方法是实现细节,容易发生变化或需要重构。因此,我们更关注公共接口的测试。另外,私有方法中可能存在复杂的逻辑,导致代码的复杂度增加。为了降低代码的复杂度,可以考虑将复杂逻辑的私有方法重构为独立的类。另一种解决方法是将方法设置为内部方法,然后使用InternalsVisibleTo进行测试。

然而,当私有方法中涉及到外部依赖时,问题就变得复杂了。在大多数情况下,可以使用依赖注入等技术来解耦类之间的依赖关系。但对于涉及第三方框架的情况,可能比较困难。可以尝试将设计重构,将第三方依赖分离出来。如果这种方法不可行,可以考虑使用Typemock Isolator。该工具的关键特性是可以模拟私有、静态等方法。

类是黑盒,应该以黑盒的方式进行测试。通过测试公共接口,我们可以确保类的功能正常。

对于评论中提到的单一责任原则(SRP),我认为它鼓励我们将功能拆分到更多的类中,而不是将所有的逻辑都集中在一个类中。例如,将复杂逻辑移动到另一个类中,并实现一个允许调用者选择同步或异步调用的异步设计模式。对于同步方法,我们编写单元测试或集成测试;而异步调用使用标准模式,复杂度较低,我们不需要对其进行测试(除非在验收测试中)。如果异步类是内部的,可以使用InternalsVisibleTo进行测试。

总结起来,私有代码的单元测试是一种重要的测试方法,但在测试过程中可能会遇到一些问题。通过重构代码、使用依赖注入或使用工具模拟私有方法,我们可以解决这些问题,确保代码的质量和功能的稳定性。

0
0 Comments

在软件开发中,单元测试是一种用于验证代码的行为是否正确的测试方法。通常情况下,我们只测试公共方法,因为作为代码的使用者,我们只关心公共方法对外提供的功能。而且,理论上来说,一个正确编写的单元测试可以完全覆盖所有私有方法的依赖关系。

然而,在某些情况下,直接对私有方法编写单元测试可能非常有用,并且能够通过单元测试更简洁地解释一些复杂的场景或边界情况。

在这种情况下,我们可以使用反射来调用私有方法。具体代码如下:

MyClass obj = new MyClass();

MethodInfo methodInfo = obj.GetType().GetMethod("MethodName", BindingFlags.Instance | BindingFlags.NonPublic);

object result = methodInfo.Invoke(obj, new object[] { "asdf", 1, 2 });

// 断言期望的结果与上面的结果是否一致

这种方法非常巧妙,我以前从未意识到反射可以做到这一点。

另外,我们还可以使用私有访问器来实现这个目的,并且还可以选择传递一个包装了真实实例的私有对象,这样会更加简洁。我认为这种方法还可以避免在签名类时可能出现的反射问题(这个我不能确定,因为我还没有遇到过这种情况)。

0
0 Comments

私有代码的单元测试是一个有争议的话题。一些人认为私有代码不应该被单独测试,因为它们是通过公共代码间接调用的,而公共代码已经通过测试覆盖到了。另一些人则认为私有代码也应该被测试,因为它们可能包含一些特定的逻辑或者边界情况,而这些情况可能无法通过公共代码的测试覆盖到。

事实上,私有代码的测试与测试公共代码是有区别的。私有代码的测试可以通过间接测试,即测试公共代码时间接覆盖到私有代码的执行路径。这种方式下,私有代码不需要被直接测试,因为它已经通过公共代码的测试间接覆盖到了。

另一种情况是私有代码根本不会被公共代码调用。这种情况下,私有代码应该被删除而不是被测试。

,我们没有必要显式地测试私有代码。因为当我们使用TDD(测试驱动开发)时,未经测试的私有代码根本不存在。因为在TDD中,私有代码只能通过从公共代码进行重构(提取方法、提取类等)的方式出现。而重构是保持行为不变的,因此也保持了测试覆盖率。而公共代码只能作为测试失败的结果出现。如果公共代码只能作为经过测试的代码出现,而私有代码只能通过从公共代码提取而来的方式出现,那么未经测试的私有代码就不会存在。

然而,有人提出了一些例外情况,比如事件处理程序或异步回调的测试。这些情况下,私有代码可能无法通过公共代码的测试覆盖到。对于这些情况,我们可以考虑使用一些技巧来间接测试私有代码。例如,可以通过模拟事件触发或者回调函数的方式来触发私有代码的执行,从而间接测试私有代码的逻辑。

是否测试私有代码取决于具体情况。对于大部分情况下,私有代码的测试可以通过间接测试公共代码来实现。但对于一些特殊情况,我们可以考虑使用一些技巧来间接测试私有代码。最重要的是,我们应该根据实际需求和项目的要求来决定是否测试私有代码。

0