2012-11-20 45 views
0

我即将钻研PHP世界中的测试,我有一些问题。我有一个处理贷款申请的控制器。然后将大部分工作委托给ProcessLoanApplication类。如何在Symfony中为此编写测试?

ApplyController

class ApplyController extends Controller 
{ 
    public function indexAction(Request $request) 
    { 
    $form = $this->createForm(new LoanApplication()); 

    if($request->getMethod() == 'POST') { 
     $form->bind($request); 

     if($form->isValid()) { 

      $session = $this->getRequest()->getSession(); 

      $loan_app_processor = new Tasks\ProcessLoanApplication($form, $session); 
      $loan_app_processor->process(); 

      return $this->redirect($this->generateUrl('apply_thanks')); 
     } 
    } 

任务\ ProcessLoanApplication

class ProcessLoanApplication 
{ 
    private $_QuickBaseModels; 
    private $_session; 
    private $_app; // submitted form data 
    private $_existingApp = false; // holds existing application in QB, if it exists 

    public function __construct(Form $form, Session $session) 
    { 
    $this->_app = $form->getNormData(); 
    $this->_session = $session; 

    // save the form data to a session 
    $session->set('application', $this->_app); 

    // create the quickbase table models objects 
    $this->_QuickBaseModels['GenFnHome\Application'] = new GenFnHome\Application(); 
    $this->_QuickBaseModels['GenFnHome\SSN'] = new GenFnHome\SSN(); 
    } 

    public function process() 
    { 
    $this->_existingApp = $this->_getExistingApplication(); 

    $app_status = $this->_existingApp[GenFnHome\SSN::LogInApplicationStatus]; 

    if(!$this->_existingApp || ($this->_existingApp && ($app_status !== 'PENDING' && $app_status !== 'OPEN' && $app_status !== 'EXPIRED'))) 
     return $this->_saveNewLoanApplication(); 

    if($app_status == 'EXPIRED') $this->_reOpenApplication(); 
    } 

有很多怎么回事,所以我会先勾勒它:

  • 用户发出请求为应用程序
  • 申请表进行验证
  • 如果有效,处理贷款申请
  • 检查,如果用户已经有一个应用程序,如果是这样 - 做X,如果不是ÿ
  • 该应用程序是在“在线数据库”坚持(QuickBase)我的应用程序通过HTTP上的XML通信(换句话说,没有真正的DB)

我的问题给社会:

  • 这里应该测试什么?我知道这在很大程度上取决于我,但是社区可能会推荐一些应该写入的基线测试。我应该测试控制器,处理器类和QuickBase类吗?
  • 我的测试应该是彼此独立的 - 也就是说,我应该单独测试每个组件,而不是让一个大型testApplication执行indexAction所做的所有操作,只查找预期的会话变量集。
  • 最后,一个测试API如何在没有实际请求的情况下调用(请求/响应)(我正在使用PHPUnit)。
  • 还有什么我应该知道的?

谢谢!

回答

0

对于控制器你应该使用功能测试(http://symfony.com/doc/2.0/book/testing.html#functional-tests)。借助它们,您可以模拟浏览器和用户的操作,例如提交表单和检查验证,数据库更改,http状态代码等。

你不应该忘记单元测试ProcessLoanApplication。

我真的不知道为什么你将表单对象传递给ProcessLoanApplication。你应该通过实体 - 它已经有normdata了。

1

这里应该测试什么?我知道这在很大程度上取决于我,但是社区可能会推荐一些应该写入的基线测试。我应该测试控制器,处理器类和QuickBase类吗?

我建议测试你构建的每个类。如果您正在使用测试驱动开发,测试会声明您正在构建的内容,而不测试任何代码。

如果我的测试是相互独立的 - 这意味着,我应该单独测试每个组件,而不是有一个庞大的testApplication,做一切该做的indexAction,只是寻找那些被置预期的会话瓦尔?

每个单元测试应该被隔离,并且应该只测试您正在测试的类。如果一个对象依赖于另一个对象,则应该使用Mock对象(使用PHPunit模拟库或其他第三方库作为Mockery)。

最后,一个测试API如何在没有实际请求的情况下调用(请求/响应)(我正在使用PHPUnit)。

您可以使用它提供简单的方法来模仿浏览器请求,详细了解在the documentation中的Symfony的WebTestCase。我们称之为功能测试。

这通常是单元测试后的阶段。在单元测试中,你将测试每个单独的类(这是一个很好的练习unit test your controller),然后编写功能测试,它结合了一切,并测试它是否像预期的那样工作。