【问题标题】:Testing class with private/protected constant使用私有/受保护常量测试类
【发布时间】:2019-04-04 23:00:08
【问题描述】:

在测试类方法时,有时我需要将返回值与某个类中定义的某个常量进行比较。

class FooBar
{
    const RANDOM = 18;
}
....
// Somewhere in test...
$this->assertEquals(FooBar::RANDOM, $mock->doSomething());

现在从 PHP 7.1 开始可以使用可见性修饰符定义类常量,这可以更改为:

private const RANDOM = 18;

但是,这会阻止测试工作,因为现在我们正在尝试访问私有常量。

所以现在我们有两个选择:

  1. 将常量声明为公共。
  2. 在测试中使用反射。意味着测试变为:

$this->assertEquals( (new ReflectionClass(FooBar::class))->getConstant('RANDOM'), $mock->doSomething() );

第一种方法感觉非常错误,因为我们不断公开只是为了测试,而不是因为类/层次结构/业务模型需要公开。

第二个感觉也不对,因为找不到这个用例 通过任何 IDE,因此任何搜索/替换/重构都会在这里失败。

所以我的问题是,是否应该在不关心重构会破坏测试的情况下使用第二种情况?或者,甚至在断言中应该不鼓励使用常量?

【问题讨论】:

    标签: unit-testing constants access-modifiers php-7.1


    【解决方案1】:

    在测试中使用常量实际上是一种不好的做法恕我直言。

    您应该测试常量的文字值。 ($this->assertSame(18, $mock->doSomething())

    为什么?

    因为测试带给您的重要价值之一是您注意到代码更改的意外后果。由于常量是私有的,它的值永远不会在类之外使用。但是许多不同的事情可能取决于它在内部的价值。

    现在想象一个不熟悉代码库的初级开发人员的任务是更改使用常量的地方之一,并将其​​从 18 更改为 16。他将去将常量的值从 18 更改为 16,然后粗略检查常量的使用位置(注意您的 doSomething() 方法)。现在,在您的方法中,您绝对需要随机数为 18,而不是 16!但是如果你使用这个常数,他永远不会知道,因为当他将它从 18 更改为 16 时,断言也会从 18 更改为 16。并且测试会通过。

    我的经验法则:

    永远不要使用从代码中提取的断言的预期值 应用程序。尽可能使用文字值。

    【讨论】:

      猜你喜欢
      • 2011-03-04
      • 2011-05-29
      • 2022-01-08
      • 2015-08-11
      • 2020-09-06
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      相关资源
      最近更新 更多