使用模拟进行单元测试(PHP)

Tow*_*wer 4 php unit-testing dependency-injection

我有一个类:

class Foo {
    function getCurrentBar() {
        $model = Query::findByPk($this->getSession()->get('current_bar')); // Pseudocode...

        return $model;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以基本上我的应用程序中一次只有一个条形,它作为整数存储在会话中.我经常调用一个辅助函数来查找模型实例,它会进行数据库查询.还有缓存,但现在无关紧要.

我的问题是:我怎么单元测试此?我测试的类需要这个.我想我可以改变会话以包含id但是这意味着我需要在数据库中有相应的模型.

最好的方法setCurrentBar()是为单元测试添加方法吗?然后我可以模拟一个条形对象并设置它,它将用于所有单元测试.那有意义吗?

Rob*_*gar 6

答案确实是依赖注入,但是你想要控制的依赖是条形的来源,而不是条形本身.

class Foo {
  private $query;

  function __construct($query)
  {
    $this->query = $query;
  }

  function getCurrentBar() {
    $model = $this->query->findByPk($this->getSession()->get('current_bar')); // Pseudocode...

    return $model;
  }
}
Run Code Online (Sandbox Code Playgroud)

所以在您的生产代码中

$query = new Query() // assuming findByPk() is made a normal non-static method
$realFoo = new Foo($query);
Run Code Online (Sandbox Code Playgroud)

但是对于单元测试......

$testFoo = new Foo(new MockQuery());
Run Code Online (Sandbox Code Playgroud)

哪个MockQuery是类的模拟版本,Query它返回模拟.