私有方法的单元测试和可能的重构

时间:2017-07-07 13:06:25

标签: c# unit-testing nunit

我目前正在以这种方式测试私有方法(使用df2 <- cbind(df1[1], read.csv(text=gsub('[:;-]+', ',', df1$product), header = FALSE, na.strings = "", col.names = paste0("product_", 1:3))) df2 # obs product_1 product_2 product_3 #1 1 apple pink lady grade 1 #2 2 apple pink lady <NA> #3 3 orange <NA> <NA> ):

nunit

我的团队不喜欢这样,因为如果我们想通过自动工具进行重构,那么将方法名称作为字符串来阻止重命名此方法。

我尝试用class Foo { private int Identity(int n) => n; } [TestFixture] class MyTests { [Test] public void TestFoo() { var myFoo = new Foo(); var identityMethod = myFoo.GetType().GetMethod("Identity", BindingFlags.NonPublic | BindingFlags.Instance); Assert.That(identityMethod.Invoke(myFoo, new []{ (object)42 }), Is.EqualTo(42)); } } 替换名称,但是:

  

由于其保护级别

,Foo.Indentity(int)无法访问

(顺便说一下,我认为这样的操作员尊重隐私保护是很奇怪的。)

那么,我可以在不牺牲可能的重构的情况下测试私有方法吗?

我被建议使私有方法受到保护并使用类test继承该类,但这并不能满足我。

免责声明:我知道有些人认为不应该测试私有方法,但这不是重点。请不要将此问题转化为有关此问题的辩论。

2 个答案:

答案 0 :(得分:2)

由于私有成员被重命名,无法确保您的代码不会中断。即使nameof也不会像您已经提到的那样有帮助,因为它无法访问私有成员。这是你不应该测试私人成员的原因之一 - 至少不是直接测试,而是通过公共API测试。

您唯一能做的就是让您的成员internal并将您的程序集标记为InternalsVisibleTo并结合您的测试程序集的名称。这样,您的测试项目就可以看到所有内部结构。请注意,对已签名的程序集执行此操作将指示friend-assembly的完全限定名称。

答案 1 :(得分:2)

在我的测试软件帽子上戴上我的教练帽......

不测试私有方法的警告经常被误解。我想说,考虑将私有方法测试的难度视为整体设计出现问题的警告。

信息隐藏和可测试性都是良好设计的特征。不幸的是,它们有时会发生冲突,而且与许多其他事情一样,你必须用你的判断来取得平衡。由于它们是设计的两个目标,因此没有绝对的答案,例如“不要测试私有方法”或“不要将任何方法设为私有”。你必须自己决定。

通常,我们认为需要测试的私有方法是设计问题的一个标志。也许它应该受到保护。也许它实际上代表了对新类的需求,您可以单独测试它。当然,我不知道,因为我不知道实际的代码。

所有这些都假定您可以控制设计。如果不是 - 如果您只负责测试 - 那么您可以不测试这些方法,或者负责任的人可以做一些事情来让您测试它们。使用InternalsVisibleTointernal方法在很多时候都是一个很好的妥协。