【问题标题】:How do I write test(s) for this in Symfony?我如何在 Symfony 中为此编写测试?
【发布时间】:2012-11-20 15:29:51
【问题描述】:

我即将深入研究 PHP 世界中的测试,但我有一些问题。我有一个处理贷款申请的控制器。然后将大部分工作委托给 ProcessLoanApplication 类。

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'));
        }
    }

Tasks\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,如果不是 Y
  • 应用程序保存在“在线数据库”(QuickBase) 中,我的应用程序通过 HTTP 上的 XML 与之通信(换句话说,没有真正的数据库)

我对社区的问题:

  • 这里应该测试什么?我知道这在很大程度上取决于我,但也许社区可以推荐一些应该编写的基线测试。我应该测试控制器、处理器类和 QuickBase 类吗?
  • 我的测试是否应该相互独立 - 意思是,我应该单独测试每个组件,而不是拥有一个庞大的 testApplication 来完成 indexAction 所做的所有事情并只查找设置的预期会话变量?
  • 最后,如何在没有实际请求的情况下测试 API 调用(请求/响应)(我使用的是 PHPUnit)。
  • 还有什么我应该知道的吗?

谢谢!

【问题讨论】:

    标签: unit-testing symfony phpunit


    【解决方案1】:

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

    我建议测试您构建的每个类。如果您使用的是测试驱动开发,则测试声明您正在构建什么,没有测试没有代码。

    我的测试是否应该相互独立 - 意思是,我应该单独测试每个组件,而不是拥有一个庞大的 testApplication 来完成 indexAction 所做的所有事情并只查找设置的预期会话变量?

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

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

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

    这通常是单元测试之后的阶段。在单元测试中,您将测试每个单独的类(unit test your controller 是一个很好的做法),然后编写您的功能测试,它将所有内容和测试结合起来,如果它按预期工作。

    【讨论】:

      【解决方案2】:

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

      您不应该忘记对 ProcessLoanApplication 进行单元测试。

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

      【讨论】:

        猜你喜欢
        • 2013-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多