Как сделать тестирование функции вставки, которая вставляет данные в MySQL, используя фиктивный объект? - PullRequest
0 голосов
/ 04 мая 2019

Я прошел через другой пост о переполнении стека о том, как выполнить тест 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);
 }
}

Я получил ошибку "Слишком мало аргументов для функции DatabaseTable :: __ construct (), 0 передано".Кто-нибудь может мне помочь написать тестовый класс?

1 Ответ

0 голосов
/ 04 мая 2019

Ваша непосредственная проблема с ошибкой решается отключением конструктора в вашем фиктивном объекте.

$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);
    }
}
...