【问题标题】:Zend Framework 2: How much unit testing to do on controllers?Zend Framework 2:对控制器进行多少单元测试?
【发布时间】:2013-09-16 17:28:10
【问题描述】:

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

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

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

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

在这种情况下,几乎所有的实际工作都是在模型内部的 updateFromArray() 方法中完成的。控制器所做的就是调用这个方法。在为这个控制器编写单元测试时,我基本上有几个测试可以测试“testAction”可以通过特定的 URL 访问,并且该操作返回 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();         
  }
}

或者,我应该两者都做吗?

【问题讨论】:

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


    【解决方案1】:

    我们两者都做,但程度不同。

    您的第一个样式,我们仅用于选择的少数系统关键功能,作为一种“冒烟测试”,以确保所有内容一起运行。请务必注意,这些不被视为真正的单元测试,而是更多“功能”测试,因为结果包括控制器与其使用/交互的任何其他类的交互。

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

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

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

    【讨论】:

    • 感谢您的回答。所以我应该直接对我的模型进行大量测试(如在我的第二个示例中),并且在测试控制器时创建“模拟”模型,因为我只是在测试控制器?您知道创建模拟对象的 Zend Framework 单元测试示例吗?
    • 我已尝试听取您的建议,并在此处发布了我的新单元测试:stackoverflow.com/questions/18789468/… 请您看一下并告诉我您的想法吗?
    【解决方案2】:

    您的控制器测试应该只测试控制器本身,而不是其他。 模型中的方法将由仅测试该模型的另一个类进行测试。

    您还应该阅读Mocking Objects,它会很有用。

    【讨论】:

    • 感谢您的回答 - 我尝试模拟一些对象,并在此处发布了我的单元测试:stackoverflow.com/questions/18789468/… 你能看看,让我知道我是否符合正确的路线吗?谢谢!
    • @user1578653 在我看来没问题。单元测试应该是隔离的。因此,如果您正在测试一个使用模型的控制器,您应该模拟您正在使用的每个模型方法,并让它们返回控制器所期望的内容。这样,如果有一天模型碰巧有一些错误,它不会影响控制器测试。
    • 感谢您的关注,也感谢您的解释——也很高兴知道模拟对象的原因!
    猜你喜欢
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 2011-11-23
    • 2013-10-12
    • 2012-09-08
    • 1970-01-01
    • 2012-12-11
    • 2011-03-31
    相关资源
    最近更新 更多