【问题标题】:PHPUnit stubbing a method for multiple instantiationsPHPUnit 为多个实例化的方法存根
【发布时间】:2014-09-04 06:31:00
【问题描述】:

我正在为一个创建自身新版本并将其插入数据库的类编写测试。 insert 方法返回一个 id,我想将它记录在原始类中,有点像这样。

class Invoice {

    public function creditInvoice() {
        $credit = new static();
        // ....
        $creditId = $credit->insert();
        $this->credited_by = $creditId;
        $this->update();
        return $credit;
    }

}

我的测试模拟了 Invoice 类并替换了更新和插入。然后它用一个函数替换 insert 以返回一个 id。

class InvoiceTest {

    public function testCreditInvoice {
        $invoice = $this->getMock('Invoice', array('update', 'insert'));
        $invoice->expects($this->any())
                ->method('insert')
                ->will($this->returnValue(1234));

        $credit = $invoice->creditInvoice();
        $this->assertTrue(
            $invoice->credited_by == 1234
        );
    }

}

这失败了。看来new static()虽然正确地制作了新版本的mock类,但并没有带来被覆盖的方法,所以credited_by实际上是null。

我看到的唯一可以解决这个问题的建议是创建一个新的测试类,它继承 Invoice 但覆盖插入函数以返回我的测试数据,但这对我来说似乎不是一个好习惯。

有没有更好的办法?

【问题讨论】:

  • 如果人们认为new static() 是不好的做法,我可以更改正在测试的代码。
  • 我通过使用依赖注入解决了这个问题,但是将一个对象传递给它自己的类的另一个实例,它也需要为空,对我来说似乎并不是一个好的编码实践(也许我'我错了)。如果有人有不涉及改变问题背景的解决方案,那么听到它仍然很棒。

标签: php unit-testing phpunit stubbing static-initialization


【解决方案1】:

new static 正在返回一个新的MockInvoice,它没有任何相关的期望。这就是为什么您的测试不起作用的原因。新对象只是一个裸 Mock 对象。

我有点困惑为什么你要创建一个新的类实例来调用insert 方法。为什么不直接打电话给$this->insert()?那你就完全不用担心new static()了。

IMO,必须创建您正在测试的类的模拟不是一个好习惯。看来您正在向数据库添加数据,我会将 insertupdate 作为单独类的方法。但是您的示例代码有点稀疏,无法完整了解您要完成的工作。

【讨论】:

  • 很抱歉,如果没有很好地解释。 ... 只是“这里发生的事情”的占位符。这是一个代表发票的对象,我想针对该发票创建一个信用。在这种情况下,Credit 是 Credit 类型的 Invoice,相同的对象,所以我创建它并使用 Invoice 数据来创建 Credit。 new static() 是为此,而不是测试。我总是使用static 而不是self,以防您以后继承该类。
猜你喜欢
  • 2015-04-09
  • 2018-10-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 2015-08-23
  • 2012-01-22
  • 1970-01-01
  • 2011-01-03
相关资源
最近更新 更多