Zend Framework 2:在控制器上进行多少单元测试?

时间:2013-09-12 10:57:05

标签: php unit-testing zend-framework zend-framework2

我刚刚开始研究Zend 2应用程序的单元测试,如果这是一个愚蠢的问题,请原谅我。

假设我有一个控制器用一组数据更新模型,并返回一些JSON:

public function testAction($data){
  $model = new \my\namespace\model();
  $model->updateFromArray($data);

  return new JsonModel(array(
        'success' => true,
  ));
}

在这种情况下,几乎所有的实际工作都是在模型内部,在updateFromArray()方法中完成的。所有控制器都会调用此方法。在为这个控制器编写单元测试时,我基本上有几个测试,测试可以通过特定的URL访问'testAction',并且该操作返回一个JsonModel的实例。

现在我知道我需要对模型的'updateFromArray'方法进行单元测试,因为它包含各种验证规则等。

我的问题是,我是否将这些测试应用于控制器(即编写一个到'testAction'的测试并发送大量不同的数据数组)或者直接通过提交大量不同的数据来测试模型数组直接到updateFromArray方法?或两者兼而有之?

我希望这是有道理的!

更新

只是为了澄清,我应该这样测试:

//send lots of different requests to the controller and see if it works
class myControllerTest extends \PHPUnit_Framework_TestCase{

  //some code...//  

  public function testWhatHappensWhenSubmitX(){
    $this->request->getPost()->set('somevariable','x');
    $result   = $this->controller->dispatch($this->request);
    $response = $this->controller->getResponse();
    $this->assertSomething();   
  }

  public function testWhatHappensWhenSubmitY(){
    $this->request->getPost()->set('somevariable','y');
    $result   = $this->controller->dispatch($this->request);
    $response = $this->controller->getResponse();     
    $this->assertSomething();     
  }

  public function testWhatHappensWhenSubmitZ(){
    $this->request->getPost()->set('somevariable','z');
    $result   = $this->controller->dispatch($this->request);
    $response = $this->controller->getResponse(); 
    $this->assertSomething();         
  }
}

或者这个:

//have lots of tests against the model
class myModelTest extends \PHPUnit_Framework_TestCase{
  public function setUp(){
    $this->model = new \my\namespace\model()
  }

  public function testWhatHappensWhenSubmitX(){
    $this->$model->doSomething('x');
    $this->assertSomething();   
  }

  public function testWhatHappensWhenSubmitY(){
    $this->$model->doSomething('y');
    $this->assertSomething();     
  }

  public function testWhatHappensWhenSubmitZ(){
    $this->$model->doSomething('z');
    $this->assertSomething();         
  }
}

或者,我应该这两个吗?

2 个答案:

答案 0 :(得分:2)

您的控制器测试应该只测试控制器本身,没有别的。 模型中的方法将由另一个仅测试该模型的类进行测试。

您还应该阅读Mocking Objects,这将非常有用。

答案 1 :(得分:2)

我们同时做到了,但不同程度。

您的第一种风格,我们仅用于少数系统关键功能,作为一种“烟雾测试”,以确保一切运行在一起。重要的是要注意,这些不是真正的单元测试,而是更多的“功能”测试,因为结果包括控制器与它使用/交互的任何其他类的交互。

您的第二种风格是我们测试控制器时最常见的风格。

您应该查看模拟框架“Phake”http://phake.digitalsandwich.com/docs/html/

这将帮助您隔离控制器的功能并正确测试。