Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用模拟对象测试向mysql插入数据的插入函数?_Php_Phpmyadmin_Phpunit - Fatal编程技术网

Php 如何使用模拟对象测试向mysql插入数据的插入函数?

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 =

关于如何使用mock对象对insert或update函数进行phpunit测试,我已经阅读了不同的堆栈溢出文章,但没有一篇解决了我的问题,因为它们不清楚

我有一个名为DatabaseTable的类,其函数如下

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 op
insert
方法将该数据传递给模拟。这实际上并不验证任何不属于测试本身的代码的功能

如果您的目标是测试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
让模拟方法返回值。在这种情况下,您希望mock
prepare
方法返回语句句柄的第二个mock,以便验证
execute