当前位置:  开发笔记 > 编程语言 > 正文

我应该测试私有方法还是仅测试公共方法?

如何解决《我应该测试私有方法还是仅测试公共方法?》经验,为你挑选了16个好方法。

我读过这篇关于如何测试私有方法的帖子.我通常不测试它们,因为我一直认为只测试从对象外部调用的公共方法会更快.你测试私人方法吗?我应该经常测试吗?



1> jop..:

我没有单元测试私有方法.私有方法是应该为类的用户隐藏的实现细节.测试私有方法会破坏封装.

如果我发现私有方法很庞大或复杂或非常重要,需要自己的测试,我只需将它放在另一个类中并在那里公开(Method Object).然后我可以轻松地测试现在存在于自己的类中的先前私有但现在公开的方法.


说私人方法不需要测试就像说汽车没问题,只要它开得好,而且引擎盖下的内容并不重要.但要知道内部的一些电缆开始松动 - 即使用户没有注意到任何东西也不是很好吗?当然,你可以公开一切,但重点是什么?你总是想要一些私人方法.
我不同意.理想情况下,在开始编写函数之前编写快速测试.考虑典型输入和输出.编写测试(不应该花费你几秒钟的时间)和代码,直到它得到正确的测试.没有理由放弃私人方法的那种工作方式.
将一段代码与汽车进行比较是错误的; 代码不随时间'_go bad_',它是_eternal_.如果你对公共接口的测试只能确定它'_looks okay_'那么你对公共代码的测试是不够的.在这种情况下,无论您如何努力,单独测试私有方法都不会使整体测试完成.集中精力测试您的公共代码作为一个整体,使用代码的内部工作知识来创建正确的方案.
"私有方法是一个应该隐藏给类用户的实现细节." 但是测试真的和"常规"(运行时)用户在类接口的同一侧吗?;)
将您想要测试的任何内容拉出到另一个类中的危险在于,最终可能会产生过度设计产品的开销,并且拥有一百万个永远不会重复使用的可重用组件.
@Pacerier你仍然不应该测试你的私人方法.如果你是,那你就错了.这可能太复杂了.类表示单元而不是方法,并且为了测试单元,您可以测试所有可能的输入和输出.私人方法不是输入.私有方法中的所有代码路径都可以通过公共方法访问 - 如果没有,那么您的方法(或您的测试输入)就会出现问题.
@Pacerier我仍然没有测试我的私有方法.我的第二段仍然适用 - 如果私有方法需要测试,我提取并测试它.
@Frank是的,你会的.这个想法是通过调用依赖于它们的公共方法来实现对私有方法的测试覆盖.直接调用私有方法并测试其输入/输出*可能*(虽然我确定有异常)意味着您的私有方法做得太多而需要重构.我看到的常见情况是转换器方法,它们在两种对象类型之间进行转换.这可以是私有的,但更好地编码为具有公共方法的单独类.测试也变得更容易.
@OCDev"不!代码确实会随着时间的推移变坏而且它不是永恒的.代码最重要的特性之一就是上下文.随着代码的变化而变化"这不是代码随着时间推移而磨损.由于变化,代码变坏了.就像我去为我的汽车增加一个增压器一样,机械师忘记将发动机拧回来,这不是汽车随着时间推移而磨损的.此外,如果您有这样的复杂性,它可能应该重构为多个类.
没有人真正意识到通过测试公用方法实际上是在隐式地测试私有方法。我是TDD的新手,但据我所知,一半正在测试中,而另一半却没有开发。它在重构。因此,您可以毫不留情地进行重构,并且可以使用许多私有方法。这些私有方法的覆盖范围已隐含在测试中。单位是什么?这是一堂课吗?一个方法?我会说这取决于上下文。它应该是代码中有意义的一部分。除非他们做一些神奇的事情,否则我们是否应该真正测试他们?
我没有得到如何测试私有事物的方法对象模式.该对象将无法在新类中调用私有方法...
@jop,所以,7年后,你***仍然***不测试你的私人方法?
在我看来,每一段代码都应该进行测试,因为测试应该保证一切都运行良好.仅涵盖公共方法的测试可能会遗漏您的私有方法中的问题.
封装和测试是正交的事情.如果某种语言不允许您轻松测试代码的某些部分,那么这是语言的限制.无需合理化这一点.
@RustyX - 不!随着时间的推移,代码确实变坏了并且它不是永恒的.代码最重要的特质之一是上下文.随着它周围的代码发生变化,它的上下文发生了变化,它就像一辆汽车一样可以打破.如果您已经设置了测试,那么在非常不方便的时候,您并不会感到惊讶.

2> Dave Sherohm..:

测试的目的是什么?

到目前为止,大多数答案都说私有方法是实现细节,只要公共接口经过充分测试和工作,它们就不会(或至少不应该)起作用.如果您测试的唯一目的是保证公共接口正常工作,这绝对是正确的.

就个人而言,我主要用于代码测试是为了确保未来的代码更改不会导致问题并帮助我调试工作.我发现像公共接口一样彻底地测试私有方法(如果不是这样的话!)进一步推动了这个目的.

考虑一下:你有公共方法A,它调用私有方法B.A和B都使用方法C.C被更改(可能由您,可能是供应商),导致A开始失败其测试.对B进行测试也不是很有用,即使它是私有的,所以你知道问题是在A中使用C,B使用C,还是两者兼而有之?

在公共接口的测试覆盖不完整的情况下,测试私有方法也会增加价值.虽然这是我们通常希望避免的情况,但效率单元测试取决于测试发现错误以及这些测试的相关开发和维护成本.在某些情况下,100%测试覆盖率的好处可能被认为不足以保证这些测试的成本,从而在公共接口的测试覆盖范围中产生差距.在这种情况下,对私有方法进行有针对性的测试可能是代码库的一个非常有效的补充.


这里的问题是那些"未来的代码变化"总是意味着重构某些类的内部运作.这种情况经常发生,编写测试会给重构带来障碍.
此外,如果您不断更改单元测试,那么您已经失去了测试中的所有一致性,甚至可能会在单元测试中创建错误.
@Sauronlord,你测试私有方法的原因是因为如果你只测试公共方法,[*当测试失败时,我们不知道失败的根本原因在哪里.它可以在`testDoSomething()`或`testDoSomethingPrivate()`中.这使得测试的价值降低.*](https://archive.is/WZsrT).以下是测试私有的更多原因http://stackoverflow.com/questions/34571/how-to-test-a-class-that-has-private-methods-fields-or-inner-classes#comment9624053_34571methods:
@ 17如果同步修改测试和实现(因为它似乎应该是这样),问题就会少得多.
@Pacerier测试代码和持续自动化测试过程之间也存在差异.显然,您应该确保您的私有方法有效,但是您不应该将测试与私有方法耦合,因为它不是软件用例的一部分.
@Pacerier无需测试即可确保该类按预期工作。该类需要经过良好的测试,以确保该类能够按预期工作。对于该类的所有用户,私有方法不是该类的一部分,只有外部公开的方法才是该类的一部分。

3> 小智..:

我倾向于遵循Dave Thomas和Andy Hunt在他们的实用单位测试一书中的建议:

一般来说,你不想为了测试而打破任何封装(或者像妈妈常说的那样,"不要暴露你的私有!").大多数情况下,您应该能够通过行使其公共方法来测试课程.如果隐藏在私有或受保护访问后面的重要功能,那可能是一个警告信号,表示还有另一个类在那里努力逃脱.

但有时我无法阻止自己测试私有方法,因为它让我感到放心,我正在构建一个完全健壮的程序.


我建议禁用以私有方法为目标的单元测试.它们是代码耦合,会给将来的重构工作带来负担,甚至有时会妨碍功能的添加或修改.在实现它们时为它们编写测试是很好的,作为一种自动的方式来断言你的实现是有效的,但将测试保持为回归并不是有益的.

4> VonC..:

我觉得有必要测试私人功能,因为我在我们的项目中遵循了越来越多的最新QA建议:

每个函数的圈复杂度不超过10 .

现在,执行这项政策的副作用是,我的许多大型公共职能部门都被分成了许多更集中,更好命名的私人职能部门.
公共职能仍然存在(当然),但基本上被简化为所谓的私人"子职能"

这实际上很酷,因为callstack现在更容易阅读(而不是大函数中的bug,我在子子函数中有一个错误,其中包含callstack中先前函数的名称,以帮助我理解"我怎么到那里"

但是,现在似乎更容易直接对这些私有函数进行单元测试,并将大型公共函数的测试留给需要解决方案的某种"集成"测试.

只需2美分.


在我的例子中,那些新的私有函数实际上是公共函数所代表的更大算法的一部分.该功能分为较小的部分,这些部分不是实用的,而是较大的过程的步骤.因此需要对它们进行单元测试(而不是一次性对整个算法进行单元测试)
为了对@jop做出反应,我觉得不需要将那些私有函数(由于将太大的复杂公共函数划分而创建)导出到另一个类中.我喜欢让他们在同一个班级中与公共职能紧密结合.但仍经过单元测试.
我的经验是,那些私有方法只是被这些公共方法重用的实用方法.有时将原始类拆分为两个(或三个)更具凝聚力的类更方便,使这些私有方法在自己的类中公开,因此是可测试的.

5> eddy147..:

是的我测试私有函数,因为虽然它们是通过您的公共方法测试的,但在TDD(测试驱动设计)中测试应用程序的最小部分是很好的.但是当您在测试单元课程中时,无法访问私有函数.这是我们测试私有方法的方法.

为什么我们有私人方法?

私有函数主要存在于我们的类中,因为我们想在公共方法中创建可读代码.我们不希望这个类的用户直接调用这些方法,而是通过我们的公共方法.此外,我们不希望在扩展类时(在受保护的情况下)更改其行为,因此它是私有的.

当我们编码时,我们使用测试驱动设计(TDD).这意味着有时我们会偶然发现一些私有且想要测试的功能.私有函数在phpUnit中是不可测试的,因为我们无法在Test类中访问它们(它们是私有的).

我们认为这里有3个解决方案:

你可以通过公共方法测试你的私人

好处

直接的单元测试(不需要'hacks')

缺点

程序员需要了解公共方法,而他只想测试私有方法

您没有测试应用程序中最小的可测试部分

2.如果私有是如此重要,那么为它创建一个新的单独类可能是一个代码

好处

你可以将它重构为一个新类,因为如果它很重要,其他类也可能需要它

可测试单元现在是一种公共方法,因此是可测试的

缺点

如果不需要,您不想创建类,并且仅由方法所来自的类使用

由于增加的开销导致潜在的性能损失

3.将访问修饰符更改为(最终)受保护

好处

您正在测试应用程序中最小的可测试部分.使用final final时,该函数不会被覆盖(就像私有一样)

没有性能损失

没有额外的开销

缺点

您正在更改对受保护的私人访问权限,这意味着它可以由其子项访问

您仍然需要在测试类中使用Mock类来使用它

class Detective {
  public function investigate() {}
  private function sleepWithSuspect($suspect) {}
}
Altered version:
class Detective {
  public function investigate() {}
  final protected function sleepWithSuspect($suspect) {}
}
In Test class:
class Mock_Detective extends Detective {

  public test_sleepWithSuspect($suspect) 
  {
    //this is now accessible, but still not overridable!
    $this->sleepWithSuspect($suspect);
  }
}

所以我们的测试单元现在可以调用test_sleepWithSuspect来测试我们以前的私有函数.


我只想指出,在TDD的原始描述中,在单元测试中,_unit_是_class_,而不是方法/函数.因此,当您提到"测试应用程序的最小部分"时,将最小的可测试部分称为方法是错误的*.如果你使用那个逻辑,你可能也在谈论一行代码而不是整个代码块.
@ eddy147单元测试来自测试驱动开发,其中单元被定义为一个类.正如Internets所发生的那样,语义已经扩展到意味着很多事情(即询问2个人单元测试和集成测试之间的区别是什么,你会得到7个答案).TDD是一种用SOLID原则编写软件的方法,包括单一责任,其中一个类只有一个责任,不应该具有高循环复杂性.在TDD中,你编写你的类并一起测试,两个单元.私有方法被封装没有相应的单元测试.

6> Matt Messers..:

出于几个原因,我不喜欢测试私有功能.它们如下(这些是TLDR人员的要点):

    通常当你想要测试一个类的私有方法时,它就是一种设计气味.

    您可以通过公共接口测试它们(这是您想要测试它们的方式,因为这是客户端调用/使用它们的方式).通过查看私有方法的所有通过测试的绿灯,您可以获得错误的安全感.通过公共接口测试私有函数的边缘情况要好得多/更安全.

    通过测试私有方法,您可能面临严重的测试重复(看起来/感觉非常相似的测试).当需求发生变化时,这会产生重大影响,因为许多测试将超过必要的测试.由于您的测试套件,它还可以让您处于难以重构的位置......这是极具讽刺意味的,因为测试套件可以帮助您安全地重新设计和重构!

我将用一个具体的例子解释每一个.事实证明,2)和3)有点错综复杂地连接,所以他们的例子是相似的,虽然我认为它们是你不应该测试私有方法的独立原因.

有一次我认为测试私有方法是合适的,但我稍后会更详细地介绍它.

我还说明为什么TDD不是最后测试私有方法的有效借口.

重构出糟糕设计的方法

我看到的最常见的(反)模式之一是Michael Feathers所谓的"冰山"课程(如果你不知道Michael Feathers是谁,去买/读他的书"有效地使用遗产代码".他是如果您是专业的软件工程师/开发人员,那么值得了解的人.还有其他(反)模式导致这个问题突然出现,但这是迄今为止我偶然发现的最常见的模式."Iceberg"类有一个公共方法,其余的都是私有的(这就是测试私有方法的原因).它被称为"冰山"类,因为通常会有一个单独的公共方法,但其余功能以私有方式的形式隐藏在水下.它可能看起来像这样:

规则评估员

例如,您可能希望GetNextToken()通过在字符串上连续调用它并看到它返回预期结果来进行测试.像这样的函数确实需要进行测试:这种行为并不简单,特别是如果您的标记化规则很复杂.让我们假装它并不是那么复杂,我们只想把空间划分为令牌.所以你写了一个测试,也许它看起来像这样(一些语言不可知的伪代码,希望这个想法很清楚):

TEST_THAT(RuleEvaluator, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    re = RuleEvaluator(input_string);

    ASSERT re.GetNextToken() IS "1";
    ASSERT re.GetNextToken() IS "2";
    ASSERT re.GetNextToken() IS "test";
    ASSERT re.GetNextToken() IS "bar";
    ASSERT re.HasMoreTokens() IS FALSE;
}

嗯,这实际上看起来很不错.我们希望确保在进行更改时保持这种行为.不过GetNextToken()是一个私人的功能!所以我们不能像这样测试它,因为它甚至不会编译(假设我们使用的某些语言实际上强制执行公共/私有,不像Python这样的脚本语言).但是如何改变RuleEvaluator课程以遵循单一责任原则(单一责任原则)?例如,我们似乎有一个解析器,标记器和评估器卡在一个类中.将这些责任分开是不是更好?最重要的是,如果你创建一个Tokenizer类,那么它的公共方法就是HasMoreTokens()GetNextTokens().该RuleEvaluator班可以有一个Tokenizer对象作为成员.现在,除了我们测试Tokenizer类而不是类之外,我们可以保持与上面相同的测试RuleEvaluator.

这是UML中的样子:

规则评估者重构

请注意,这种新设计增加了模块化,因此您可能会在系统的其他部分中重复使用这些类(在您不能之前,私有方法根​​据定义不可重用).这是打破RuleEvaluator的主要优势,同时增加了可理解性/局部性.

测试看起来非常相似,除了它实际上会编译,因为该GetNextToken()方法现在在Tokenizer类上公开:

TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);

    ASSERT tokenizer.GetNextToken() IS "1";
    ASSERT tokenizer.GetNextToken() IS "2";
    ASSERT tokenizer.GetNextToken() IS "test";
    ASSERT tokenizer.GetNextToken() IS "bar";
    ASSERT tokenizer.HasMoreTokens() IS FALSE;
}

通过公共接口测试私有组件并避免测试重复

即使你认为你不能将你的问题分解为更少的模块化组件(如果你只是尝试这样做,你可以95%的时间),你可以通过公共接口简单地测试私有函数.很多时候私人成员不值得测试,因为他们将通过公共界面进行测试.很多时候,我看到的测试看起来非常相似,但测试两种不同的功能/方法.最终发生的事情是,当需求发生变化时(他们总是这样做),你现在有2个破坏的测试而不是1.如果你真的测试了所有的私有方法,你可能会有更多像10个破坏的测试而不是1个.简而言之. ,测试私有函数(通过使用FRIEND_TEST或公开或使用反射),否则可能通过公共接口进行测试可能导致测试重复.你真的不想要这个,因为没有什么比你的测试套件更让你失望的伤害.它应该减少开发时间并降低维护成本!如果您测试通过公共接口进行测试的私有方法,那么测试套件可能会做相反的事情,并积极地增加维护成本并增加开发时间.当你公开私人功能,或者你使用类似FRIEND_TEST和/或反思的东西时,你通常会在长期内后悔.

考虑以下可能的Tokenizer类实现:

在此输入图像描述

假设它SplitUpByDelimiter()负责返回一个数组,使得数组中的每个元素都是一个标记.而且,让我们说这GetNextToken()只是这个向量的迭代器.所以你的公开测试看起来像这样:

TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);

    ASSERT tokenizer.GetNextToken() IS "1";
    ASSERT tokenizer.GetNextToken() IS "2";
    ASSERT tokenizer.GetNextToken() IS "test";
    ASSERT tokenizer.GetNextToken() IS "bar";
    ASSERT tokenizer.HasMoreTokens() IS false;
}

让我们假装我们拥有Michael Feather所称的摸索工具.这是一个工具,可以让您触摸其他人的私人部分.一个例子FRIEND_TEST来自googletest,或者语言是否支持反射.

TEST_THAT(TokenizerTest, canGenerateSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);
    result_array = tokenizer.SplitUpByDelimiter(" ");

    ASSERT result.size() IS 4;
    ASSERT result[0] IS "1";
    ASSERT result[1] IS "2";
    ASSERT result[2] IS "test";
    ASSERT result[3] IS "bar";
}

那么,现在让我们说需求发生变化,令牌化变得更加复杂.您决定一个简单的字符串定界符是不够的,并且您需要一个Delimiter类来处理该作业.当然,你会期望一个测试中断,但是当你测试私有函数时疼痛会增加.

何时可以测试私有方法?

软件中没有"一刀切".有时候"打破规则"是可以的(而且实际上是理想的).我强烈主张不在可能的情况下测试私有功能.当我认为没关系时,有两种主要情况:

    我已经与遗留系统进行了广泛的合作(这就是为什么我是Michael Feathers的忠实粉丝),我可以肯定地说,有时候测试私有功能是最安全的.将"特征测试"纳入基线可能特别有用.

    你很匆忙,必须在这里和现在做最快的事情.从长远来看,您不希望测试私有方法.但我会说重构通常需要一些时间才能解决设计问题.有时你必须在一周内发货.没关系:快速而肮脏并使用摸索工具测试私有方法,如果这是您认为最快,最可靠的完成工作的方法.但要明白,从长远来看,你所做的事情并不是最理想的,请考虑回到它(或者,如果它被遗忘但你稍后再看,修复它).

可能还有其他情况可以.如果你认为这没关系,并且你有充分的理由,那就去做吧.没有人阻止你.请注意潜在的成本.

TDD借口

顺便说一句,我真的不喜欢使用TDD作为测试私有方法的借口的人.我练习TDD,我不认为TDD强迫你这样做.您可以先编写测试(针对您的公共接口),然后编写代码以满足该接口.有时我会为公共接口编写一个测试,我也会通过编写一个或两个较小的私有方法来满足它(但是我不直接测试私有方法,但我知道它们有效或者我的公共测试会失败).如果我需要测试该私有方法的边缘情况,我会编写一大堆测试,通过我的公共接口来测试它们.如果你无法弄清楚如何击中边缘情况,这是一个强有力的迹象,你需要使用自己的公共方法重构为小组件.这是一个标志,你是私人功能做得太多,超出了课堂的范围.

此外,有时候我发现我写了一个目前咀嚼得太大的测试,所以我想"呃我以后会有更多的API可以用来进行测试"(我我会把它评论出来并保留在我的脑海里.这是我遇到的很多开发人员将开始为他们的私人功能编写测试的地方,使用TDD作为替罪羊.他们说"哦,我需要一些其他测试,但为了编写测试,我需要这些私有方法.因此,因为我不编写测试就不能编写任何生产代码,所以我需要写一个测试对于私人方法." 但他们真正需要做的是重构为更小和可重用的组件,而不是在当前类中添加/测试一堆私有方法.

注意:

我刚回答了一个关于使用GoogleTest测试私有方法的类似问题.我大多修改了这个答案,在这里更加语言无关.

PS这是Michael Feathers关于冰山课程和摸索工具的相关讲座:https://www.youtube.com/watch?v = 4cVZvoFGJTU



7> 17 of 26..:

我认为最好只测试一个对象的公共接口.从外部世界的角度来看,只有公共界面的行为很重要,这就是你的单元测试应该针对的.

一旦你为一个对象编写了一些可靠的单元测试,你就不想再回过头来改变那些测试,因为接口背后的实现发生了变化.在这种情况下,您已经破坏了单元测试的一致性.



8> chrissie1..:

如果您的私有方法未通过调用您的公共方法进行测试,那么它在做什么?我说私人不受保护或朋友.


谢谢.这是一个令人惊讶的被低估的评论,特别是仍然相关,即使在写完近8年之后.

9> Adam Davis..:

如果私有方法定义良好(即,它具有可测试的功能并且不打算随时间改变)那么是.我测试了一切有意义的东西.

例如,加密库可能会隐藏它使用私有方法执行块加密的事实,该方法一次只加密8个字节.我会为此编写一个单元测试 - 它不是要改变,即使它是隐藏的,如果它确实中断(例如由于未来的性能增强),那么我想知道它是私有函数破坏了,而不仅仅是其中一个公共职能破裂了.

它可以加快调试速度.

-亚当



10> Jader Dias..:

如果您正在开发测试驱动(TDD),您将测试您的私有方法.


不正确,您测试您的公共方法,一旦测试通过,您就可以将公共方法中的代码提取到私有方法中,从而实现"清理"步骤.测试私有方法是一个坏主意海事组织,因为它使改变实施方式更难(如果有一天你想改变你如何做一些事情,你应该能够改变它,运行所有测试,如果你新做的方式事情是正确的,他们应该通过,我不想要改变我所有的私人测试).
您将在重构时提取私有方法http://agiletips.blogspot.com/2008/11/testing-private-methods-tdd-and-test.html

11> maxbog..:

我不是这个领域的专家,但是单元测试应该测试行为,而不是实现.私有方法严格地是实现的一部分,因此不应该测试恕我直言.



12> 小智..:

我们通过推理测试私有方法,我的意思是我们寻找至少95%的总类测试覆盖率,但只有我们的测试调用公共或内部方法.为了获得覆盖,我们需要根据可能发生的不同场景对公共/内部进行多次调用.这使得我们的测试更加关注他们正在测试的代码的目的.

特朗普对你所关联的帖子的回答是最好的.



13> scubabbl..:

我认为单元测试用于测试公共方法.您的公共方法使用您的私有方法,因此它们也间接地进行测试.



14> dkinzer..:

我一直在讨论这个问题,特别是在试用TDD的时候.

我发现在TDD的情况下,我认为可以彻底解决这个问题.

    测试私有方法,TDD和测试驱动的重构

    测试驱动开发不是测试


综上所述:

当使用测试驱动的开发(设计)技术时,私有方法应该仅在已经工作和测试的代码的重新分解过程中出现.

根据流程的本质,从经过全面测试的功能中提取的任何简单实现功能都将是自我测试(即间接测试覆盖).

对我而言,似乎很清楚,在编码的开始部分,大多数方法将是更高级别的功能,因为它们封装/描述了设计.

因此,这些方法将是公开的,并且测试它们将是足够容易的.

私有方法将在一切运行良好之后出现,我们为了可读性清洁而重新考虑因素.



15> Adron..:

如上所述,"如果你不测试你的私人方法,你怎么知道他们不会破坏?"

这是一个重大问题.单元测试的一个重点是知道事情在何时,何时以及如何破坏.从而减少了大量的开发和QA工作量.如果测试的所有内容都是公开的,那么您就没有诚实的报道和对班级内部的描述.

我发现执行此操作的最佳方法之一是将测试引用添加到项目中,并将测试放在与私有方法并行的类中.放入适当的构建逻辑,以便测试不会构建到最终项目中.

然后,您将拥有测试这些方法的所有好处,您可以在几秒钟内找到问题,而不是几分钟或几小时.

总而言之,是的,单元测试你的私有方法.


我不同意。“如果不测试您的私有方法,您怎么知道它们不会中断?” :我知道这是因为,如果我的私有方法被破坏,那么依赖于那些私有方法的测试我的公共方法的测试将失败。我不想每次改变主意如何实现公共方法时都不必更改测试。我还认为,单元测试的主要目的不是特别地了解哪一行代码是错误的,而是让您或多或少地确信自己在进行更改(对私有方法)时没有破坏任何内容。

16> 小智..:

你不应该.如果您的私有方法具有必须测试的足够复杂性,则应将它们放在另一个类上.保持高凝聚力,一个班级应该只有一个目的.类公共接口应该足够了.

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有