使用PHPUnit和PDO测试覆盖率 [英] Testing coverage with PHPUnit and PDO
问题描述
作为练习,我正在尝试使用PHPUnit达到100%的代码覆盖率,这几乎可以实现,但这是我发现很难的错误位.
As an exercise, I'm trying to reach 100% code coverage using PHPUnit, this is almost there, but it's the error bits which I've found difficult.
我有一个示例类,与真实代码有类似的问题,确切的代码不是问题,但是行为是相同的.
I have an example class which I has a similar issue to my real code, the exact code is not the issue, but the behaviour is the same.
class DBAccess {
private $db;
public function __construct( \PDO $db ) {
$this->db = $db;
}
public function select () {
$data = false;
if ( $stmt = $this->db->prepare("select * from user") ){
if ( $stmt->execute() ){
$data = $stmt->fetchAll();
}
else {
echo "Something went wrong"; // How to get here!
}
}
return $data;
}
}
这是停止100%覆盖率的一行.困难在于我需要准备通过,但执行失败.我已经通过将无效的外键或字段传递给表的大号来进行更新,但是通过选择,我不确定会出什么问题.
It's the one line which is stopping the 100% coverage. The difficulty is that I need the prepare to pass, but the execute to fail. I've managed this on updates by passing invalid foreign keys or fields to large for the table, but with a select, I'm not sure what can go wrong.
我的测试是...
class DBAccessTest extends TestCase {
private $pdo;
public function setUp() {
$this->pdo = new PDO("mysql:host=172.18.0.2;dbname=test",
"test", "RkqwD1gjOdjkrwTt");
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
}
public function testSelect() {
$test = new DBAccess( $this->pdo );
$this->assertTrue($test->select() != false );
}
}
我可以想到两种可能性
- 假设如果准备工作成功了,那么执行者也会这样做,但对此并不特别满意.
- 以某种方式覆盖连接以使其以可控的方式失败.
推荐答案
This is exactly what PHPUnit's test doubles are for. And kudos for designing your classes in an object oriented way, so it's easy to inject mocks into them.
<?php
use PHPUnit\Framework\TestCase;
class DBAccessTest extends TestCase
{
public function test_something_goes_wrong()
{
// Create test doubles.
$stmtMock = $this->createMock(\PDOStatement::class);
$pdoMock = $this->createMock(\PDO::class);
// Configure the stubs.
$stmtMock->method('execute')
->willReturn(false);
$pdoMock->method('prepare')
->willReturn($stmtMock);
// Inject the mock.
$test = new DBAccess($pdoMock);
// Assert.
$this->assertFalse($test->select());
}
}
这篇关于使用PHPUnit和PDO测试覆盖率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!