如何对数据库插入函数PDO进行单元测试



在下面的代码中,我应该如何编写单元测试?我应该如何模拟数据库?嘲笑有什么意义?想象一下,在同一个保存类中,我们有一个setDb方法,它是注入数据库依赖项。

namespace Samttsrc; 
use Resque;
class MoHandler {

    public $db; 
    public $resque; 
    private function getAuthToken($input){
        $arg = json_encode($input);
        return `./registermo $arg`;
    }
    public function setDatabase(Database $db) {
        $this->db = $db; 
    }
    public function setResque($resque) {
        $this->resque = $resque;
    }
    public function save($stackContents){
        if( !is_array($stackContent) || count($stackContents) == 0 )
            return false; 
        $this->db->query("INSERT INTO 
            `mo` (msisdn, operatorid, shortcodeid, text, auth_token, created_at)
             VALUES (:msisdn, :operatorid, :shortcodeid, :text , :auth_token, NOW())"
        );
        $this->db->beginTransaction();
        foreach($stackContents as $item) {
            $auth_token = $this->getAuthToken($stackContents);
            $this->db->bind(':msisdn', $item['msisdn']); 
            $this->db->bind(':operatorid', $item['operatorid']); 
            $this->db->bind(':shortcodeid', $item['shortcodeid']); 
            $this->db->bind(':text', $item['text']); 
            $this->db->bind(':auth_token', $auth_token); 
            $this->db->execute();
        }
        $this->db->endTransaction();
        echo 'A new job stack has been inserted into database ' . PHP_EOL ; 
    }

    /**
     * creating an extra queue in redis is much more efficent than 
     * inserting into mysql for every single request 
     * this function pack data and use batch insert to minimize 
     * database connection
     *  
     * @param  [array] $queueContents [description]
     * @return [boolean] 
     */
    public function createJobStack($input, $queue = null){
        if(! is_array($input)) {
            throw new InvalidArgumentException;
        }
        // create job stack in redis with "current queue name" 
        // to avoid name collision with possible future job stack
        $stack = $queue .'-jobstack';
        $size  = $this->getSize($stack);
        if($size < Config::$minQueueSize) {
            // check incoming MO and if they are buggy 
            // don't let them pass !
            if(! Validator::validate($input, Config::$validKeys)) {
                echo 'buggy MO' . PHP_EOL ; 
                return false; 
            }
            $this->resque->push($stack, $input);
            echo 'new item has been added to ' . $stack . PHP_EOL; 
            echo 'current stack size is : ' . $size . PHP_EOL; 
        }else {
            $stackContents = [];
            for($i = 1; $i <= Config::$minQueueSize; $i++){
                array_push($stackContents, $this->resque->pop($stack));
            }
            // save the stack into database 
            $this->save($stackContents);
        }
        return true;
    }

    public function getSize($stack) {
        return $this->resque->size($stack);
    }

    public function setUp() {
        $this->setDatabase((new Database));
        $this->setResque((new Resque));
    }
    public function perform(){
        $this->createJobStack($this->args, $this->queue);
    }
}

我已经编辑并添加了整个类。我需要多少断言?

这里是一个测试用例,用于检查错误的输入数据,并使用正确的数据进行第二次测试。在第二个场景中,我们测试了正确的方法调用,并使用正确的数据调用了绑定方法的一个示例。

<?php

namespace SamttsrcTests; 

use SamttsrcMoHandler;
class MoHandlerTest extends PHPUnit_Framework_TestCase {
    protected $database;
    protected $handler;
    public function setUp()
    {
        $this->database = $this->getMock('SamttsrcDatabase',array('query','beginTransaction','bind','execute','endTransaction'));
        $this->handler = new MoHandler();
        $this->handler->setDatabase($this->database);
    }
    public function test_save_with_invalid_data()
    {
        $input = array();
        $this->database
            ->expects($this->never())
            ->method('query')
        ;
        $this->assertFalse($this->handler->save($input)); // Check te return value
    }
    public function test_save_with_correct_data()
    {
        $input = array(
            array(
            'msisdn' => 'msisdn',
            'operatorid' => 'operatorid',
                'shortcodeid' =>'shortcodeid',
                'text' =>'text'
            )
        );
        $this->database
            ->expects ($this->exactly(5))->method('bind')->withAnyParameters();
        $this->database
            ->expects($this->at(2))
            ->method('bind')
            ->with(':msisdn','msisdn')
        ;
        $this->database
            ->expects($this->once())
            ->method('query')
        ;
        $this->assertNull($this->handler->save($input)); // Check te return value
    }
}

希望这能帮助

进一步参考:

http://www.andrejfarkas.com/2012/07/phpunit-at-method-to-check-method-invocation-at-certain-index/

最新更新