2013-05-30 47 views
1

我想单元测试一个具有公共和私有方法的类,我想单元测试已被设置为私有的特定方法(基于受保护的抽象)。我不能公开这个方法,也不想通过完整的过程来测试这个方法,我只关心这个方法的输入参数和返回符合期望。如何写私人方法的单元测试

我不想使该方法公开为这个问题亮点:

Making a private method public to unit test it...good idea?

我的问题是,什么是测试私有方法和技术,我赞成,为什么各种方式的?

我已阅读此问题(How do you unit test private methods?),但想知道接受的答案是否仍然是最佳答案,或者在数年之后还有更好的方法。

如果这个问题被认为是How do you unit test private methods?重复我要在那里加我的意见,并要求更新,请大家指教。

+0

使用反射技术 – user1283633

+1

看看这个 http://bugsquash.blogspot.it/2009/05/testing-private-methods-with-c-40.html –

+0

@FabioMarcolini看起来很有趣,我会仔细看看。 –

回答

1

您是否希望能够在测试中调用您的私有方法并查看它是如何工作的?

您可以从您的类派生并添加公用方法,该方法将调用您想要测试的方法。很简单。虽然我不会建议测试私有方法。我想不出有一个理由去做。我很想看到会改变我的想法的例子。

+0

+1是的我同意,如果调用方法发生了某种变化,我不会孤立地测试私有方法,因为它会在未来引入脆弱性,在这种情况下,没有测试覆盖这个,但我认为我将要做的事实际上是继承并调用基础实现,即使我会嘲笑相当多的内部元素,并允许测试随着将来修订版本的变化而发展。 –

+0

我最终做的是从我想测试的类中派生出来,并重写了我的私有方法,捕获了输入和输出,并将其用于我的测试。 –

+1

甚至有一个名称,你做了什么 - “提取并覆盖” –

2

我已经阅读了这个问题(你如何单元测试的私有方法?),但 想知道如果接受的答案仍然是最好的答案,或者 经过多年有一个更好的办法。

我会避免接受的答案。

我可以跳进一个关于测试公共接口并且不担心内部事件的长篇大论,但这可能不太现实。

有两个直接的选择,我可以看到:

  • 的反思看法,排序的一劈,但至少你可以得到某种形式的测试去的。这也很可能是最快速的工作。
  • 摘要使用类似的策略模式,注入行为纳入对象本身(或手动有物体内部new了相关策略)的私有方法的行为。这个独立的战略项目可以独立进行测试。

也就是说,你不应该在这种情况下经常发现自己。如果你这样做,你需要退后一步,回顾你如何设计你的课程,并可能对它们进行审查,以使它们更加开放和可测试。

+0

+1感谢您的意见,我也曾考虑过反思,但希望尽可能避免它,因为我怀疑这需要付出相当大的努力? –

+0

@Monkieboy如果你只是为少数几件物品做的话,那么它并不是真的。当然,代码更加冗长,并且不是强类型或任何内容,但您可以将其视为OK交易。 –

7

如果无法通过有意义的公共方法测试类的私有方法,那就意味着什么是错与类的设计。如果是很辛苦,所以你希望打破测试,以测试其功能的一个子集,那么我建议打破类成其逻辑块和单独测试的测试类。

也许你有机会去重构代码,使私营方法成为了一些其他类(ES)的公共方法。一个很好的例子是一个课程,它安排一些计时器的工作以便稍后处理。工作方法可能被实现为私有方法,这使得难以以简单的方式进行测试而无需调度计时器并等待其执行工作方法。在执行时间非常快的测试中不理想。一个简单的方法是将调度工作代码分成两个独立的类。私人工作方法然后成为Worker类的公共方法,使其非常易于测试。虽然拆分计划和工作人员代码意味着您将难以达​​到100%的覆盖率,但您至少会覆盖工作代码。解决这个问题的一个办法是使用像Quartz.net这样的工具来实现调度器类,这样你就可以很容易地对调度器进行单元测试以及工作者代码。

+0

+1是的,你是对的,它可能表明有一些设计缺陷,但我的理由是,为现有的功能写一个测试需要花费很多工作量,这对目前的变化来说已经超出了范围。正在制作。我确实希望在这个周围进行测试,但现在不能这样做。 –

+0

您在此输入的内容实际上是我同意的内容,因此会鼓励人们对此答案进行投票,因此它确实可以突出显示它的优点,但无法按照我的具体情况中的建议进行操作。 –

-1

使用反射。如果您不想自己琢磨反射,那么您可以使用位于Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll中的Microsoft PrivateObject类。但是在配合MSTest和NUnit时出现问题 - Using both MSTest and NUnit?

1

在VS 2005,2008和2010中,您可能有私有访问者。你右键点击一个私人功能,并选择“创建私人访问者”...

在VS 2012中,这个功能已经不知怎么了。唯一方便的方法是使用PrivateObject。您可以查看MSDN中使用PrivateObject的示例。

0

如果你正在使用VS 2005或以上,使用以下步骤

  1. 打开包含私有方法的源代码文件。
  2. 右键单击私有方法,然后选择“创建单元测试”。 这将显示“创建单元测试”对话框。在可见树结构中,只选择私有方法的复选框。
  3. (可选)在“创建单元测试”对话框中,可以更改“输出”项目。您也可以单击设置重新配置生成单元测试的方式。
  4. 单击确定。 这将创建一个名为VSCodeGenAccessors的新文件,其中包含特殊的访问器方法,用于检索正在测试的类中的私有实体的值。您可以在测试项目文件夹中的解决方案资源管理器中看到新文件。 如果您的测试项目在此之前没有单元测试,还会创建一个用于存放单元测试的源代码文件。与包含私有访问器的文件一样,包含单元测试的文件也在解决方案资源管理器中的测试项目中可见。
  5. 打开包含您的单元测试的文件并滚动到私有方法的测试。找到标有// TODO:注释的语句,并按照注释中的说明完成它们。这有助于测试产生更准确的结果

欲了解更多信息,请参阅this

它看起来在内部它使用反射来调用私有方法。但它的工作。

+0

谢谢@kleopatra,修改完成。 – Priyang

0

我真的来到这里来回答这个问题,直到我意识到我不应该单元测试私有方法。原因是因为私人方法是一个过程中的一部分,是一些较大逻辑的一部分。

单元测试旨在针对类的接口进行测试。我的想法是,我应该确保质量控制,当我的班级按照意图的方式使用时。因此,单元测试私有方法是没有用的,因为它永远不会暴露给消费者(谁正在执行)。您需要针对消费者可以使用您的课程的情况进行单元测试。

如果你发现自己绝对需要对私有的东西进行单元测试,那么可能需要重新考虑该方法的位置,或者代码的细分方式。我得出的结论是,如果我需要对私有方法进行单元测试,那么可以将它封装到静态实用程序类中的方法是9/10次。