在一个类中,方法是否相互依赖是可以的,这些方法是封装在一起的吗?这会影响单元测试吗?或者术语Unit
是针对整个班级而不是班级自己的方法。
可以做这样的事情:
<?php
class foo {
protected $baz;
protected $bar;
private function checkBaz($baz) {
// do some checking
}
private function checkBar($bar) {
// do some checking
}
public function setBaz($baz) {
if($this->checkBaz($baz)){
$this->baz = $baz;
}
}
public function setBar($bar) {
if($this->checkBar($bar)){
$this->bar = $bar;
}
}
}
我在想是否要将此类中的绑定方法用于另一个类,我必须稍微重写一下这个方法,如果将方法封装起来就像将方法参数插入到方法参数中,那么我就会徘徊,这是OOP中的常见做法,还是我应该坚持认为类是高内聚方法和属性的封装,并将其视为一个完整的可重用和测试Unit
。
答案 0 :(得分:2)
是的,在类内部调用方法绝对没问题。事实上,它受到了鼓励。仅仅存在protected
和private
方法应该是一个死的赠品。你只能从类中调用那些需要由public
方法触发的地方,所以是的,你的例子如果完全符合这些方法应该如何使用。
一般而言,在单元测试方面唯一重要的是整个对象的行为方式。它的public
组件很重要,这是其他代码与之交互的内容,也是其他代码观察到的内容。无论你的对象/类是什么类型的内部调用都完全取决于它自己的判断力。如果它有助于你的类结构将某些代码放在不同的方法中并将它们与外界隐藏起来,那么就这样吧。
答案 1 :(得分:2)
是的,执行这样的方法调用非常好。它们被标记为private
,因此它们仍然封装在您的班级中,并且不会暴露给外部世界。
如果这些方法调用开始导致类/对象偏离其主要目的,打破single responsibility principle,则值得考虑将类分解为更精细的单元并通过{{3}注入此新依赖项}。例如,checkBaz
方法正在执行数据库查找。
在单元测试方面,你真正想做的是dependency injection,为你的foo类创建一个接口并实现它。这意味着无论何时编程,您都要编写合同 - 允许您轻松模拟IFoo
实现。
例如:
class Foo implements IFoo {
}
您的界面将如下所示:
interface IFoo
{
public function setBaz($baz)
public function setBar($bar)
}
我还建议关注program to an interface not implementation并首先使您的类名称为大写。如果这是您或您的团队做出的决定,那么这完全是您的召唤。
答案 2 :(得分:1)
非公开方法没有错。实际上,类只应导出最少的公共方法,以允许其他类使用其服务。越多的外部类知道你的类的内部工作,在不破坏外部依赖性的情况下更改类的内部工作就越困难。
应该通过间接调用来测试非公共方法。应该存在最终调用每个方法的情况,即使它是通过间接调用(公共方法调用私有方法等)。如果一个方法从未在单元测试中执行,那么这是一个很好的指示,它实际上是死代码,可以完全从类中删除。
理论上,您可以通过对类进行子类化并将受保护的方法提升为public来直接测试类的受保护方法,但不建议这样做,因为它暴露了类的内部工作,而您实际上并不想这样做。