Unit testing 如何实现cakephp的单元测试

Unit testing 如何实现cakephp的单元测试,unit-testing,cakephp,Unit Testing,Cakephp,我正试图对cakephp进行单元测试,我想知道是否有人可以提供一些关于如何为特定控制器方法编写测试的信息: public function paymentmethod() { $this->layout='dashboard'; $billingaddressInfo = $this->Dashboard->find('all',array('fields' => array('Address_book_id','first_name','last_na

我正试图对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')); 
    }           
}
我真的在寻找关于测试方法的哪些部分以及断言什么的建议,我不寻找任何人来编写代码,而只是对如何实现这一点的经验评估。我对它非常陌生,非常感谢您的一些意见。

将代码的各个部分分解,使它们可以单独测试 将“查找”操作移动到模型将是一个良好的开端,这样您就可以测试操作的各个部分

比如,

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很高兴我能帮上忙。祝你的项目好运!