Stubbing&在Zend Framework应用程序中的PHPUnit中进行模拟

时间:2012-02-26 08:41:34

标签: zend-framework mocking phpunit stubbing

我是Zend Framework和PHPUnit的新手。我正在将遗留应用程序转换为MVC架构,并且正在尝试编写单元测试。我对单元测试概念有点熟悉,但总的来说,它一直困扰着存根和嘲弄。例如,请考虑以下

在控制器操作中,我试图测试我传入的成员ID。然后我使用ID初始化成员对象。然后,我调用与成员对象关联的多个方法,并将返回值分配给视图对象。

class A extends Zend_Controller_Action {
    public function viewAction() {
        $member = new Member($this->getRequest()-> getParam('id'));

        //perform various calls on the member object 

        $gender = $member->getGender();
        ...

        //assign the return values to the view object

        $this->view->assign('gender',$gender);   
        ...

     }
}

如何在我的测试中模拟$ member变量,以便我可以自定义方法返回值?

如果我的理解不正确,我会非常感谢一些指导。

谢谢!

2 个答案:

答案 0 :(得分:6)

如果我理解正确,你就是在为这个行动写一个测试。在这种情况下,由于在方法内部创建了新实例,因此无法模拟$ member。这就是为什么我们都尽可能多地在对象图中尽可能多地浮动new语句(DI)。

通常有一个特殊的PHPunit测试用例Zend_Test_PHPUnit来测试你的控制器。

但事实上,正确测试ZF控制器非常困难甚至不可能(意味着完全隔离)。您最好测试应用程序的其余部分,通用库等。

换句话说,在ZF1逻辑中,控制器是中央布线位置(在引导程序之后),传统上使用了许多new语句。显然,这会导致不可测试性,因为每个创建而不是注入的实例都是不可修复的。

正如@vascowhite指出的那样,追求精益控制器也是一件好事。这意味着,尽可能多地将逻辑移动到模型层。这将导致更少的冗余(DRY)和更好的可测试性。

但要注意不要让你的模型膨胀。有时您可能希望将一些代码考虑到其他组件中。

另一个问题是你不能模拟前端控制器,因为它是一个单例。所以你真的没有很多选择来测试这样的动作。唯一的选择是注入成员实例或从注册表中获取它(也不是一个好主意)。

所以,鉴于所有这一点很明显,你无法完成动作测试的完全隔离。但是

ZF2将更容易测试。

答案 1 :(得分:1)

最好从功能测试覆盖控制器开始。在这种情况下,您可以绕过这个模拟问题并获得更好的测试覆盖率。控制器总是很难被单元测试覆盖,因为它们是强耦合的。

要使用ZF编写功能测试,请考虑使用Codeception:http://codeception.com/01-27-2012/bdd-with-zend-framework.html

此外,还有一些例子,如何对控制器进行单元测试。但是,从那时起,我建议在对它们进行功能测试后对单元测试控制器进行测试。

http://codeception.com/docs/06-UnitTestsAndBDD#TestingController