0

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

应用控制器

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

我对社区的问题:

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

谢谢!

4

2 回答 2

1

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

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

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

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

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

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

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

于 2012-11-20T19:05:29.223 回答
0

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

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

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

于 2012-11-20T16:33:58.213 回答