繁体   English   中英

模拟专用字段的最佳技术/变通办法?

[英]Best technique/workaround for mocking assignment of private field?

TDD和Mockito在这里测试了newb ...我最近发现了有关注入私有字段模拟的信息,并试图弄清我的想法。

很可能我对这个特定问题的想法是完全错误的,但是仅仅是我经常发现一种情况,我想测试调用特定方法是否导致分配了私有字段:在调用之前为null ,并在调用后将其设置为任何类的实例。

在您开始运行测试方法时,模拟的私有字段是所讨论类的子类,因此显然测试null是没有意义的/不起作用。 同样,如果您的方法导致分配了该字段,则意味着模拟变量已被真正的实例替换。 因此,即使调用了方法,也不会导致与模拟变量的任何交互。 无论如何,如果测试只是检查创建和分配,则没有理由希望在测试中与其进行任何交互。

显然,答案是在应用程序类中创建一个public get()方法或一个public create()方法。 但这给我一种不好的感觉,因为显然这只是出于测试目的。

顺便说一句,无疑会有很多人比我在TDD上拥有更多的经验,他们会说我太细粒度了,不应该测试像字段分配这样具体的东西。 但是我对TDD的最极端方法的理解是“没有测试就不要编写一行代码”。 我确实在现阶段尽可能地坚持这一点。 凭借经验,也许我将对如何以及何时脱离该原则有更深入的了解。

只是对我而言,对字段的分配似乎是(宿主类的)“类事件”,与任何其他类型的事件一样有价值,例如,将实例分配给对象之后,在字段上调用方法领域。 我们不应该能够以某种方式对其进行测试吗? 在这种情况下,可以接受测试的Mockito专业人士会做什么呢?

后来...

法比奥(Fabio)的评论突显出,作为新生代人,在“切勿编写未经测试的行”与“仅测试公共方法”之间的紧张关系令人费解:这不可避免地暴露出比我想要的东西更多的东西,纯粹是为了测试。

他所说的“一直更改测试”也使我感到困扰:如果我们注入模拟的私有字段并使用它们,那么如果我们更改“实现细节”,我们将不得不更改测试。 这个想法也不会让我感到恐惧:意识到了变更的需求,您查看了现有测试方法的解释性名称,并确定哪些不再适用,当然您会创建新的方法……测试代码,像应用程序代码一样,必须一直更改,对吧?

测试代码不是某种形式的模具或模具,可以指导和约束应用程序代码,但同时又可以与之分离吗? 通过Mockito允许我们模拟私有字段,已经授予了特权访问形式...谁说这种特权访问应该正确扩展到多远?

甚至以后

杰夫·鲍曼指出这是一个DUP 我并不完全相信,因为我要问的是一个非常具体的问题,可能有一个特定的答案(某些Mockito检测分配的方式)。 但是他的回答似乎非常全面,我正在尝试全面理解这一切……包括整个依赖注入问题……以及您似乎在“扭曲”公共接口以使应用程序类成为“类”时必须做出的妥协。可测试,如您所愿。

简单的例子:你需要写一个类Class1两种方法Method1Method2 ,其返回由一些提供的值Helper类。

  1. [测试]开始为第一种方法编写测试-无法编译
  2. [生产]创建类Class1和Method1-编译成功并测试失败
  3. [生产]在Method1中,您将创建Helper新实例,并调用其中一些返回期望值的方法-测试通过
  4. [测试]为相同的Method1创建另一个测试用例-测试失败
  5. [生产]对Method1进行更改以满足两个测试用例-测试是绿色的
  6. [生产]如果有可能,请在Method1一些重构-测试必须保持绿色
  7. [测试]为Method2创建测试,该测试将更新Class1一些公共字段Field1无法编译
  8. [生产]在Class1创建方法Method2和字段Field1编译-确定,测试失败
  9. [生产]在Method2创建Helper类的新实例,将其命名为method并用期望值更新Field1测试通过
  10. [测试]为Method2创建另一个测试用例-测试失败
  11. [生产]对Method2进行更改以满足两个测试用例-测试是绿色的

现在,你已经实现所需的行为,并注意到这两个Method1Method2创建的实例Helper类。

  1. [生产]因此,您决定声明类型为Helper私有字段,并在两种方法中都使用它-所有测试均失败-因为未实例化私有字段。
  2. [生产]-您在构造函数中实例化新实例-所有测试均为绿色

以后,如果您决定将Helper类的创建移到外部并作为构造函数的参数传递给Class1 ,则只需更改生产代码,测试就会显示您在不更改测试的情况下进行了任何操作。

我的回答的重点是,如果您认为“我想编写此行代码-如何测试”,它会在您遇到的那种情况下解决问题。
尝试首先考虑要测试的内容,然后编写测试,然后考虑如何实现它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM