【问题标题】:How to approach unit test for cakephp如何对 cakephp 进行单元测试
【发布时间】:2013-05-29 05:26:15
【问题描述】:

我正在尝试为 cakephp 进行单元测试,我想知道是否有人可以提供一些关于如何为特定控制器方法编写测试的输入:

public function paymentmethod() {

    $this->layout='dashboard';
    $billingaddressInfo = $this->Dashboard->find('all',array('fields' => array('Address_book_id','first_name','last_name'),'conditions' => array('Dashboard.customer_id' => $this->Session->read('customer_id'),'address_type'=>'1')));
    $billingaddress = array();
    if(is_array($billingaddressInfo) && count($billingaddressInfo) > 0) {
        foreach($billingaddressInfo as $key=>$value) {
            $billingaddress[$value['Dashboard']['Address_book_id']] = $value['Dashboard']['first_name'].' '.$value['Dashboard']['last_name'];
        }   
    }
    $this->set('billingaddress',$billingaddress);

    $fullbillingaddress = $this->Dashboard->find('all',array('fields' => array('Address_book_id','customer_id','first_name','last_name','address_line_1','address_line_2','city','state','country','zipcode'),
                                    'conditions' => array('Dashboard.customer_id' =>$this->Session->read('customer_id'))));

    $this->set('fullbillingaddress',$fullbillingaddress);   
    $shippingaddress = $this->Dashboard->find('list',array('fields' => array('first_name'),'conditions' => array('Dashboard.customer_id' => $this->Session->read('customer_id'),'address_type'=>'2')));

    $this->set('shippingaddress',$shippingaddress);

    $this->loadModel('Paymentmethod');

    if(!empty ($this->request->data)) {     
        $getpaymentform = $this->request->data['Paymentmethod'];            
        $getpaymentform['card_number'] = $this->encryptCard($getpaymentform['card_number']);            
        if($this->request->data['Paymentmethod']['is_default']==1) {                
            $this->Paymentmethod->updateAll(array('is_default'=>'0'),array('Paymentmethod.customer_id' =>$this->Session->read('customer_id')));
        }
        $this->Paymentmethod->save($getpaymentform);

    }
    $paymentdata = $this->Paymentmethod->find('all',array('conditions' => array('Paymentmethod.customer_id' =>$this->Session->read('customer_id'))));
    $this->set('paymentdata',$paymentdata);
    $this->render();

    if(!empty ($this->request->data)) {
        $this->redirect(array('action'=>'paymentmethod')); 
    }           
}

我真的在寻找关于测试方法的哪些部分以及断言什么的建议,而且我不是在寻找任何人来编写代码,而只是对你将如何处理这个问题进行有经验的评估。我对它很陌生,非常感谢您提供一些意见。

【问题讨论】:

    标签: unit-testing cakephp


    【解决方案1】:

    分解代码的各个部分,使其可单独测试

    将您的“查找”操作移至模型将是一个好的开始,这样您就可以测试操作的各个部分。

    例如;

    class Dashboard extends AppModdel
    {
        
        public function getBillingAddress($customerId)
        {
            $billingaddressInfo = $this->find('all',
                array(
                    'fields' => array(
                        'Address_book_id',
                        'first_name',
                        'last_name',
                    ),
                    'conditions' => array(
                        'Dashboard.customer_id' => $customerId,
                        'Dashboard.address_type' => 1,
                    ),
                )
            );
        
            $billingaddress = array();
            if(is_array($billingaddressInfo) && count($billingaddressInfo) > 0) {
                foreach($billingaddressInfo as $key=>$value) {
                    $billingaddress[$value['Dashboard']['Address_book_id']] = $value['Dashboard']['first_name'].' '.$value['Dashboard']['last_name'];
                }   
            }
        
            return $billingaddress;
        }
    }
    

    (注意:使用 virtualField 可能会更容易做到这一点,但这不是这个问题的主题)

    而且,在您的控制器内部,只需:

    $customerId = $this->Session->read('customer_id');
    $billingAddress = $this->Dashboard->getBillingAddress($customerId);
    

    将该代码移至您的模型不仅会产生更简洁的代码(参见我的示例),您还可以将getBillingAddress() 方法与其他代码分开测试。

    要进一步了解单元测试的方法/内容,请务必查看 CakePHP 本身的源代码。在 lib/Cake/test 目录中,您可以找到 Cake 本身的单元测试,其中包含有关如何测试应用程序某些部分的宝贵信息(例如,如何测试模型、控制器、组件等)

    【讨论】:

    • 非常感谢。这是一个很好的例子。您是否建议在最后也测试重定向,或者也应该重构?
    • 你应该测试什么是重要的测试(取决于你的情况)。然而,像$this->encryptCard() 这样的东西看起来确实与数据相关,所以不应该是控制器的一部分。此外,您在进行重定向之前手动调用render(),所以我想知道重定向是否会按预期工作?
    • 非常感谢您的意见。我只是继承了代码,只需要重新审视它。
    • @DevatoTech 很高兴我能提供帮助。祝你的项目好运!
    猜你喜欢
    • 1970-01-01
    • 2012-01-08
    • 2013-11-18
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 2019-01-05
    • 2011-03-16
    相关资源
    最近更新 更多