我对单元测试很新;我需要使用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;
}
如果您需要更多说明,请告诉我,我们非常感谢您的帮助!
答案 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抛出异常!)
玩得开心!