[英]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
两种方法Method1
和Method2
,其返回由一些提供的值Helper
类。
Class1
和Method1-编译成功并测试失败 Helper
新实例,并调用其中一些返回期望值的方法-测试通过 Method1
创建另一个测试用例-测试失败 Method1
进行更改以满足两个测试用例-测试是绿色的 Method1
一些重构-测试必须保持绿色 Method2
创建测试,该测试将更新Class1
一些公共字段Field1
无法编译 Class1
创建方法Method2
和字段Field1
编译-确定,测试失败 Method2
创建Helper
类的新实例,将其命名为method并用期望值更新Field1
测试通过 Method2
创建另一个测试用例-测试失败 Method2
进行更改以满足两个测试用例-测试是绿色的 现在,你已经实现所需的行为,并注意到这两个Method1
和Method2
创建的实例Helper
类。
Helper
私有字段,并在两种方法中都使用它-所有测试均失败-因为未实例化私有字段。 以后,如果您决定将Helper
类的创建移到外部并作为构造函数的参数传递给Class1
,则只需更改生产代码,测试就会显示您在不更改测试的情况下进行了任何操作。
我的回答的重点是,如果您认为“我想编写此行代码-如何测试”,它会在您遇到的那种情况下解决问题。
尝试首先考虑要测试的内容,然后编写测试,然后考虑如何实现它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.