2009-11-10 154 views
2

我读过很多Zend控制器测试教程,但我找不到解释如何测试使用模型和嘲笑这些模型的控制器。单元测试Zend控制器模拟模型和服务

我有以下控制措施: -

function indexAction(){ 
    // Get the cache used by the application 
    $cache = $this->getCache(); 

    // Get the index service client and model 
    $indexServiceClient = new IndexServiceClient($this->getConfig()); 
    $indexModel = $this->_helper->ModelLoader->load('admin_indexmodel', $cache); 
    $indexModel->setIndexServiceClient($indexServiceClient); 

    // Load all the indexes 
    $indexes = $indexModel->loadIndexes(); 

    $this->view->assign('indexes', $indexes); 
} 

目前,我有一个非常基本的测试案例: -

public function testIndexActionRoute() { 
    $this->dispatch('/admin/index'); 
    $this->assertModule('admin', 'Incorrect module used'); 
    $this->assertController('index', 'Incorrect controller used'); 
    $this->assertAction('index', 'Incorrect action used'); 
} 

这个测试工作,但它调用了真正的模型和服务,这有时意味着它超时并在测试环境中失败。为了正确地进行单元测试,我需要对IndexServiceClient和IndexModel进行嘲笑和期望 - 这是如何完成的?

回答

4

好吧,由于我在这里看到的回复并不多,我会尝试添加我的2cents(可能有争议)。 下面写的答案是我的IHMO和非常主观(我认为不是很有用,但我们在这里我们去)

我认为控制器不是一个很好的适合单元测试。您的业​​务逻辑层,模型等是一致的。 控制器与UI连接并将系统集成在一起可以这么说 - 因此对我来说它们更适合集成和UI测试 - 这是Selenium等软件包所使用的。

在我看来,测试应该很容易实现,以便测试实施的总体工作量足以获得回报。对我来说,连接控制器的所有依赖关系似乎(我的知识当然有限)有点太多了。

想想它的另一种方式是 - 控制器中实际发生了什么。同样,IHMO应该主要是业务逻辑和用户界面之间的胶水级别。如果你将许多业务逻辑放入控制器中,将会产生不利影响(例如,它不会轻易无法统计)。

这是当然的各种理论。希望有人能提供更好的答案,并且实际展示如何轻松连接控制器进行单元测试!

+0

在与我的同事们讨论后,得出了同样的结论。使用适当的模拟对控制器进行单元测试需要付出很大的努力,回报很少。尤其是我们的模型层完成了大部分工作,并且具有广泛的测试覆盖范围,而控制器非常薄。 – 2009-11-12 11:09:08

2

一位同事提出的一种可能的解决方案是使用Zend Controller Action Helper注入模拟依赖关系。这应该在理论上工作,但我还没有广泛地测试这种方法

这是这样做的一个例子。

class Mock_IndexModel_Helper extends Zend_Controller_Action_Helper_Abstract { 

    private $model; 

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

    /** 
    * Init hook 
    */ 
    public function init() {    
     $this->getActionController()->setIndexModel($this->model); 
    } 

} 


class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { 

    public $bootstrap = BOOTSTRAP; 

    public function setUp(){ 
     parent::setUp(); 
    } 


    /** 
    * Test the correct module/controller/action are used 
    */ 
    public function testIndexAction() {     
     $mockIndexModel = $this->getMock("IndexModel"); 

     Zend_Controller_Action_HelperBroker::addHelper(new Mock_IndexModel_Helper($mockIndexModel)); 

     $this->dispatch('/admin/index'); 

     $this->assertModule('admin', 'Incorrect module used'); 
     $this->assertController('index', 'Incorrect controller used'); 
     $this->assertAction('index', 'Incorrect action used'); 
    }  
}