【问题标题】:What is the best way to unit test constructors?对构造函数进行单元测试的最佳方法是什么?
【发布时间】:2016-01-07 18:52:39
【问题描述】:

我有以下测试方法来测试构造函数是否正常工作:

选项#1

public function testConstructWorksProperly()
{
    $id = 1;
    $name = 'name';
    $foo = new Foo($id, $name);
    $this->assertEquals($id, $foo->getId());
    $this->assertEquals($name, $foo->getNome());
}

选项 #2

public function testConstructWorksProperly()
{
    $id = 1;
    $name = 'name';
    $foo = new Foo($id, $name);
    $this->assertAttributeEquals($id, 'id', $foo);
    $this->assertAttributeEquals($name, 'name', $foo);
}

在选项 #1 中,我需要创建 getter 来断言构造函数正常工作,而在选项 #2 中,我使用断言来检查构造函数是否正确设置了属性。

我想知道每次我需要公开访问这些属性时总是使用选项 #1,因为我节省了时间和 LOC,而不是为 getIdgetName 编写另外 2 个测试。

使用选项二似乎是一种白盒测试。 但是...

有一种说法:“每个测试一个断言”,所以,如果我的构造函数有 6 个参数,我将需要 6 个断言和 6 个 getter 来公开测试这些方法。

你会使用哪个选项?

【问题讨论】:

  • 除了选项,也许只有我一个人,我会通过参数传递Foo的实例
  • @Andrew,我正在测试 Foo 方法,而不是使用它作为参数。
  • 除非你的 setter 做一些不寻常的事情,否则单元测试 getter 和 setter 没有多大意义
  • 我使用反射来验证构造函数是否正确保存了内部值。这主要用于测试真正需要以特定方式设置这些值的特定功能。正如上面的@RobbieAverill 所示,您不必总是测试这些。在我们的代码中,继承和其他因素意味着某些字段需要特定的数据,这就是使用反射的原因,以便我们可以验证保存的数据,作为跨不同应用程序测试共享库代码的一部分。

标签: php unit-testing testing phpunit


【解决方案1】:

在做任何事情之前,你必须问自己:测试构造函数的目的是什么?你这样做的真正目的是什么?

如果您想要在单独的测试中隔离每个方法,您应该使用 option #2(选项 #1 也称为您的 getter)但我真的认为,在“现实生活”中项目,测试构造函数没有任何价值。

构造函数只是告诉你应该如何构建对象,你不应该对它有太多的逻辑,你所有的测试都依赖于构造函数,所以如果它不工作,你的测试将会失败。

如果你对构造函数有逻辑,你可以使用命名构造函数来简化事情(是的,测试它们)。


P.S.1:不要忘记访问器不是那么好,在添加它们(尤其是设置器)之前,你应该好好考虑一下。我们应该始终关注行为而不是对象的状态。


P.S.2:选项 #2 应该是这样的:

public function testConstructWorksProperly()
{
    $id = 1;
    $name = 'name';
    $foo = new Foo($id, $name);
    $this->assertAttributeEquals($id, 'id', $foo);
    $this->assertAttributeEquals($name, 'name', $foo);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 2010-09-07
    • 2011-06-06
    • 2010-09-27
    • 1970-01-01
    • 2010-09-05
    相关资源
    最近更新 更多