Я только что нашел несколько дней назад, как это сделать с последней версией Mockery, на что намекал и Дэйв Маршалл (но немного по-другому).
Давайте предположим, что у меня есть класс Database с методами для составления списка таблиц, удаления таблицы и получения схемы базы данных, и я хочу создать метод «reset», который использует эти 3 метода.
Вот как я издевался над ним с помощью насмешек.
<?php
class Database
{
public function getSchema($version = null)
{
//...
}
public function listTables()
{
//...
}
public function dropTable($table)
{
//...
}
public function reset($version = null)
{
$tables = $this->listTables();
foreach ($tables as $table)
{
$this->dropTable($table);
}
$schema = $this->getSchema($version);
foreach ($schema as $query)
{
$this->conn->query($query);
}
}
}
Итак, чтобы проверить метод reset
, описанный выше, вот как я высмеял getSchema
, listTables
и dropTable
:
class DatabaseTest extends \PHPUnit_Framework_TestCase
{
//...
public function test_reset_list_existing_tables_deletes_them_then_create_a_new_schema()
{
$app = new \Silex\Application();
$ConnectionMock = \Mockery::mock('\Doctrine\DBAL\Connection');
$ConnectionMock
->shouldReceive('query')
->with('SQL query 1')
->once()
->ordered('reset');
$ConnectionMock
->shouldReceive('query')
->with('SQL query 2')
->once()
->ordered('reset');
$app['db'] = $ConnectionMock;
$Database = \Mockery::mock('\Database[listTables,dropTable, getSchema]', array($app));
$Database
->shouldReceive('listTables')
->once()
->ordered('reset')
->andReturn(array('system', 'users'));
$Database
->shouldReceive('dropTable')
->with('system')
->once()
->ordered('reset');
$Database
->shouldReceive('dropTable')
->with('users')
->once()
->ordered('reset');
$Database
->shouldReceive('getSchema')
->with(1)
->once()
->ordered('reset')
->andReturn(array('SQL query 1', 'SQL query 2'));
$Database->reset(1);
}
}
В частности, посмотрите, как я создаю макет:
$Database = \Mockery::mock('\Database[listTables,dropTable, getSchema]', array($app));
Я перечисляю метод, который хочу смоделировать, в «[]» и передаю конструктор Database
в виде массива во втором параметре mock
.
reset
, который я хочу проверить, не является поддельным, так что фактическая реализация выполняется, когда я выполняю $Database->reset(1);
.