3

我是 Zend 框架和 PHPUnit 的新手。我正在将遗留应用程序转换为 MVC 架构并尝试编写单元测试。我对单元测试概念有些熟悉,但一般都坚持使用 stubbing 和 mocking。例如考虑以下

在我试图测试的控制器操作中,我传入了一个成员 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 变量,以便我可以自定义方法返回值?

如果我在这里的理解不正确,我将不胜感激一些指导。

谢谢!

4

2 回答 2

6

如果我对您的理解正确,那么您正在为此操作编写测试。在这种情况下,不可能模拟 $member,因为新实例是在方法内部创建的。这就是为什么我们都努力new在对象图中尽可能多地浮动我们的语句(DI)。

通常有专门的 PHPunit 测试用例Zend_Test_PHPUnit来测试你的控制器。

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

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

正如@vascowhite 指出的那样,争取精益控制器通常也很好。这意味着,将尽可能多的逻辑移动到您的模型层。这将同时减少冗余(DRY)和更好的可测试性。

但也要注意不要让你的模型膨胀。在某一时刻,您可能希望将一些代码分解到其他组件中。

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

因此,鉴于所有这些,很明显,您无法对动作测试进行完全隔离。但

不过,ZF2 将更容易测试。

于 2012-02-26T11:27:06.157 回答
1

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

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

此外,还有一些示例,说明如何对控制器进行单元测试。但是,真诚地,我建议在对控制器进行功能测试后对控制器进行单元测试。

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

于 2012-02-27T23:37:00.327 回答