Php 如何使用模拟对象测试向mysql插入数据的插入函数?
关于如何使用mock对象对insert或update函数进行phpunit测试,我已经阅读了不同的堆栈溢出文章,但没有一篇解决了我的问题,因为它们不清楚 我有一个名为DatabaseTable的类,其函数如下Php 如何使用模拟对象测试向mysql插入数据的插入函数?,php,phpmyadmin,phpunit,Php,Phpmyadmin,Phpunit,关于如何使用mock对象对insert或update函数进行phpunit测试,我已经阅读了不同的堆栈溢出文章,但没有一篇解决了我的问题,因为它们不清楚 我有一个名为DatabaseTable的类,其函数如下 class DatabaseTable { public $table; function __construct($table) { $this->table=$table; } function insert($record) { global $pdo; $keys =
class DatabaseTable
{
public $table;
function __construct($table)
{
$this->table=$table;
}
function insert($record) {
global $pdo;
$keys = array_keys($record);
$values = implode(', ', $keys);
$valuesWithColon = implode(', :', $keys);
$query = 'INSERT INTO ' . $this->table . ' (' . $values . ') VALUES (:' .
$valuesWithColon . ')';
$stmt = $pdo->prepare($query);
$stmt->execute($record);
}
和测试类作为
<?php
require 'classes/databasetable.php';
class savedataTest extends \PHPUnit_Framework_TestCase{
public function testValidData() {
$validData = [
'firstname' => 'John',
'lastname' => 'Smith',
'email' => 'john@example.org'
];
$this= 'abc';
$users = $this->getMockBuilder('DatabaseTable')->getMock();
$users->expects($this->once())
->method('insert')
->with($this->equalTo($validData));
$valid = insert($validData);
$this->assertTrue($valid);
}
}
通过禁用模拟对象中的构造函数,可以解决即时错误问题
$users = $this->getMockBuilder('DatabaseTable')
->disableOriginalConstructor()
->getMock();
然而,我更担心的是,你的测试似乎并没有真正测试任何有用的东西。您有一个在测试中创建的数据集,然后使用您在同一测试中创建的no opinsert
方法将该数据传递给模拟。这实际上并不验证任何不属于测试本身的代码的功能
如果您的目标是测试DatabaseTable类,那么实际的模拟边界是PDO对象,您需要检查DatabaseTable类是否实际正确地调用了prepare
和execute
<?php
require 'classes/DatabaseTable.php';
class savedataTest extends \PHPUnit_Framework_TestCase
{
public function testValidData()
{
$validData = [
'firstname' => 'John',
'lastname' => 'Smith',
'email' => 'john@example.org'
];
$table = 'users';
$stmt = $this->createMock('PDOStatement');
$stmt->expects($this->once())
->method('execute')
->with($validData)
->willReturn(true);
global $pdo;
$pdo = $this->createMock('PDO');
$pdo->expects($this->once())
->method('prepare')
->with("INSERT INTO {$table} (firstname, lastname, email) VALUES (:firstname, :lastname, :email)")
->willReturn($stmt);
$users = new DatabaseTable($table);
$users->insert($validData);
}
}
谢谢你的回答。正如您所说,我正在尝试测试DatabaseTable类。但我不知道如何测试它。我能够测试与数据库连接无关的其他函数。但我在测试DatabaseTable类时遇到了一个问题。请详细说明如何测试类是调用prepare还是execute。提前感谢。@DamodarBhattarai我用模拟PDO对象的测试编辑了响应。您可以使用willReturn
让模拟方法返回值。在这种情况下,您希望mockprepare
方法返回语句句柄的第二个mock,以便验证execute
。