我开始使用PHPUnit对我的PHP应用程序进行单元测试。我知道单元测试独立运行非常重要,因此您可以知道测试失败时的位置。我正在努力理解的一件事是如何与父类隔离地测试子类。例如,我的大多数模型扩展了一个“基本模型”,它具有模型应具有的大部分功能。
<?php
class BaseModel
{
public function save($data) {
// write $data to the database
$dbAdapter->save($data);
}
}
class RegularModel extends BaseModel
{
public function save($data) {
// clean up $data before passing it to parent
if (isset($data['foo'])) {
unset($data['foo']);
$data['bar'] = 'foo';
}
parent::save($data);
}
}
# Unit Test
class RegularModelTest extends PHPUnit_Framework_TestCase
{
public function testSaveMethodCallsParent() {
$data = array('foo' => 'yes');
$model = new RegularModel();
$model->save($data);
// assert parent received data correctly
}
}
我不确定如何在不调用一堆不必要的代码的情况下测试我的RegularModel
。我也在进行一些自动加载,所以当它调用save保存时,它实际上会尝试保存到测试数据库。我宁愿嘲笑这个,因为我不关心当我在测试RegularModel
时测试BaseModel
时是否实际写入数据库。或者我在想这一切都错了?在测试这样的情况时你有什么建议?
答案 0 :(得分:2)
最好的办法是在测试$dbAdapter
时嘲笑RegularModel
。当您仍在执行父类的代码时,由于is-a关系,该代码确实是RegularModel
单元的一部分。
唯一的方法是提供BaseModel
的不同实现。您可以在单独的进程中运行这些测试,也可以使用Runkit在运行时交换其他实现。这些都有缺点 - 复杂性,性能降级和不稳定性 - 在我看来价格过高。
答案 1 :(得分:1)
根据定义,子类与它们的超类紧密耦合,因此实际上没有办法单独测试子类。
但是,如果超类有一个广泛的测试套件,那么你通常可以确信你可以通过覆盖子类中实现的方法来测试子类。超类测试套件涵盖了超类功能。