PHPUnit测试用例

时间:2014-06-01 19:49:15

标签: php unit-testing testing phpunit testcase

我对单元测试很新;我需要使用PHPUnit测试来编写测试用例!由于我没有看到任何测试用例,我不确切知道如何测试,如何编写测试用例...如果你可以帮助我测试我的一个小方法,我可以获得良好的测试和理解逻辑。所以我想知道你是否介意帮助我测试以下方法(最好是使用PHPUnit,但任何其他测试用例都可以帮助我理解逻辑):

static public function get_accepted_images($limit, $page, $uuid) {

    try {
        $conn = new pdo_connect();

        $query = "  SELECT ....";

        $result = $conn->prepare($query);
        $result->bindParam(':uuid', $uuid);
        $result->execute();
        $array_result = $result->fetchAll(PDO::FETCH_OBJ);
        $paginate_result = WS_Utility::paginate_array($array_result, $page, $limit);
        $result_Set = array($paginate_result, TRUE);
    } catch (Exception $e) {

        $result_Set = array($e->getMessage(), FALSE);
    }


    return $result_Set;
}

如果您需要更多说明,请告诉我,我们非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您无法对此方法进行单元测试,因为它有太多副作用。特别是结果会因所选数据库而异。

要测试此方法,您需要进行功能测试。这与单元测试没有太大区别(也可以由phpunit完成,但是您需要在运行测试之前准备数据库。这样,您将获得可预测的结果,并且您可以测试您的逻辑功能

我在测试上面的方法时没有多大意义,但我建议更好地测试WS_Utility::paginate_array(),因为除了从DB中获取之外,这是唯一一个执行任何逻辑的函数调用。

答案 1 :(得分:0)

首先,您应该将此方法更改为非静态。

public function get_accepted_images($limit, $page, $uuid) {
    try {
        $conn = new pdo_connect();
        $query = "SELECT...";
        $result = $conn->prepare($query);
        $result->bindParam(':uuid', $uuid);
        $result->execute();
        $array_result = $result->fetchAll(PDO::FETCH_OBJ);
        $paginate_result = WS_Utility::paginate_array($array_result, $page, $limit);
        $result_Set = array($paginate_result, TRUE);
    } catch (Exception $e) {
        $result_Set = array($e->getMessage(), FALSE);
    }
    return $res;
}

下一步是使用一些集成测试(NOT UNIT TESTING)来处理这种方法 当您进行集成测试时,您并不关心该方法是如何实现的,但您应该确切地知道方法的合同(例如:在此输入上接收此输出,在此上下文中接收此异常等等) )

基于对此方法合同的了解,您开始进行集成测试:

class ImageDatabaseHelperIntegrationTest extends PHPUnit_Framework_TestCase
{
//The most simple test. When no images exists in the DB what happens?
public function testWhenNoImagesExistsReturnCorrectResult() {
    $sut = new ImageDatabaseHelper(); //I dont know what is the name of the class
    $actual = $sut->get_accepted_images(1,1,1);
    $expected = array(null, FALSE); //?? I dont know what the result is. you know this
    $this->assertEquals($expected, $actual);
}


//You should keep doing like this. 
//The next tests will include inserting data in the database, and testing what is the output




编辑:

  

user3421904写道:但为什么不静态?我们不能这样做:$actual = images::get_accepted_images(1, 1, 11);这个就像我一样   好!这是错的吗?

没错。但是,如果您要对其他消耗ImageDatabaseHelper的组件进行单元测试,则无法对其进行模拟。原因如下:

我们假设您使用的ImageService类直接使用get_accepted_images静态方法。像这样:

class ImageService {

    public function getAcceptedImages() {
        $images = ImageDatabaseHelper::get_accepted_images(1,1,1);

        //...
        //more code 
        //...

        return $images;
    }
}

如何在不访问数据库的情况下测试getAcceptedImages方法?你不能,对吧?

现在假设您使用非静态方法。

class ImageService {
    private $imageDatabaseHelper;

    public function __construct(ImageDatabaseHelper $imageDatabaseHelper = null) {
       if(!$imageDatabaseHelper) {
          $this->imageDatabaseHelper = new ImageDatabaseHelper();
       }
       else {
          $this->imageDatabaseHelper = $imageDatabaseHelper;
       }
    }


    public function getAcceptedImages() {
        $images = $this->imageDatabaseHelper->get_accepted_images(1,1,1);

        //...
        //more code 
        //...

        return $images;
    }
}

这可以轻松测试!!!

class ImageServiceTest extends PHPUnit_Framework_TestCase {
    protected $sut;    

    protected $imageDatabaseHelperDouble;

    public function setUp() {
      $this->imageDatabaseHelperDouble = $this->getMockBuilder('ImageDatabaseHelper')->disableOriginalConstructor()->getMock();
      $this->sut = new ImageService($this->imageDatabaseHelperDouble);
    }


    public function testGetAcceptedImagesWhenCalledShouldCallImageDatabaseHelper() {
       $this->imageDatabaseHelperDouble->expected($this->once())->method('get_accepted_images')->with(1,1,1);
       $this->sut->getAcceptedImages();
    }


    public function testGetAcceptedImagesWhenCalledShouldReturnImages() {
       $this->imageDatabaseHelperDouble->expected($this->any())->method('get_accepted_images')->will($this->returnValue(array("hi im an image", "me tooo")));
       $actual = $this->sut->getAcceptedImages();

       $expected = array("hi im an image", "me tooo");
       $this->assertEquals($expected, $actual);
    }

}
你知道吗?模拟的ImageDatabaseHelper会覆盖ImageService使用的原始ImageDatabaseHelper,他认为他正在使用它。从这里你可以做任何你想做的事! (这还包括使ImageDatabaseHelper抛出异常!)

玩得开心!