如何测试返回模型的服务方法?

时间:2014-10-21 01:38:59

标签: testing phpunit

所以我有一个修改模型对象的服务方法

public function doSomething() {
    $model = new Model();

    // Modify the model with a bunch of private methods

    return $model;
}

如果我想测试doSomething,我真的只有$ model可以使用。我可以在$ model上编写断言的唯一方法是使用它的公共接口。

$this->assertEquals($model->getName(), 'name');

让我感到困惑的是,我究竟在用这个断言测试什么?我测试getName是否正常工作还是我测试doSomething是否正常工作?

为了让我测试doSomething,我必须假设getName有效。那么如何确保是这种情况呢?

2 个答案:

答案 0 :(得分:1)

您与doSomething()的合同是,它必须返回类型为" Model"的对象。您的合同不是getName()处理返回的对象。因此,测试$ model的类型是正确的:

$this->assertInstanceOf('Model', $model); 

文档:PHPUnit -> assertInstanceOf()


作为一个提示," [i] deally,每个测试用例独立于其他测试用例" 2014-10-21 wikipedia.org/wiki/Unit_testing

因此,在test_doSomethingTest *()中,您应该只测试该函数中发生的事情。检查返回类型,以及该功能发生的任何事情。测试getName()应该在它自己的test_getName *()。

答案 1 :(得分:1)

根据您的代码,我会测试我返回了Model的实例。然后使用公共访问器或assertAttributeEquals检查对象的属性是否正确。这会测试模型的getter,但具有某些属性的对象是您期望发生的。

虽然你的类正在创建对象并修改它。我会改变方法以Model作为参数。这样在我的测试中我可以创建一个mockModel并确保使用正确的参数调用任何公共setter。这样做,我不必担心Model对已设置属性的任何逻辑。

例如:

测试功能:

public function testDoSomething() {
    $mockModel = $this->getMock('Model');

    $mockModel->expects($this->once())
              ->method('foo')
              ->with('some argument');

    $mockModel->expects($this->once())
              ->method('bar')
              ->with('some other argument');

    $sut = new SUT();

    $sut->doSomething($mockModel);
}

您的功能doSomething只需要成为:

public function doSomething(Model $model) {
   /** Do stuff with private methods **/
}

现在,您可以确保Model的属性设置为正确的值,而不是取决于类中可能存在或不存在的逻辑。您还在帮助指定Model需要填写的合同。您所依赖的任何新方法都将在您的集成/系统测试中出现。