У меня есть установка, похожая на этот упрощенный пример (должна работать, копируя ее напрямую), но метод, который я хочу смоделировать Controller->setModel()
, не осмеивается. Также не отображаются ошибки:
<?php
use PHPUnit\Framework\TestCase;
// Implementation
class Model
{
// The constructor here would receive a PDO, but that's not important
public $data = [
['id' => 1, 'text' => 'nope'],
['id' => 2, 'text' => 'no'],
['id' => 3, 'text' => 'not']
];
public function getItem($id)
{
// And here we would query with the PDO instead, but again
// the question is more about mocking the setModel() method
return $this->data[$id];
}
}
abstract class Endpoint
{
public function __construct()
{
echo "\n1. Calling abstract class constructor\n";
$this->model = $this->setModel();
}
abstract protected function setModel();
}
class Controller extends Endpoint
{
public function getStuff($id)
{
echo "3. Getting stuff from controller\n";
$data = $this->model->getItem($id);
return ['id' => $data['id'], 'text' => $data['text']];
}
protected function setModel()
{
echo "2. Setting ACTUAL model of controller\n";
$config = 'sqlite:myfile.sqlite3'; // Suppose this file exists and is valid
$pdo = new \PDO($config);
return new Model($pdo);
}
}
// Test
final class ControllerTest extends TestCase
{
public function testExample()
{
$mockModel = \Mockery::mock('FakeModel')
->shouldReceive('getItem')
->andReturn(['id' => 123, 'text' => 'myCustomText']);
$mock = \Mockery::mock('Controller')->makePartial()
->shouldAllowMockingProtectedMethods();
$mock->shouldReceive('setModel')->andReturn($mockModel);
$controller = new Controller();
$result = $controller->getStuff(2);
$this->assertEquals('myCustomText', $result['text']);
}
}
Результат теста следующий. Исключение PDOException связано с тем, что драйвер php5 -sqlite больше не доступен для моей локальной виртуальной машины (Ubuntu 18.04). Я использую Docker образ для установки, но та же проблема с поддельными происходит и в этом тоже. Но не в этом суть - дело в том, чтобы высмеивать setModel()
:
1. Calling abstract class constructor
2. Setting ACTUAL model of controller
Time: 110 ms, Memory: 7.25MB
There was 1 error:
1) ControllerTest::testExample
PDOException: could not find driver
/home/juha/koodaus/pastes/backend/test/Foo/FooTest.php:45
/home/juha/koodaus/pastes/backend/test/Foo/FooTest.php:26
/home/juha/koodaus/pastes/backend/test/Foo/FooTest.php:63
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
Как вы можете видеть из 2-го отладочного отчета - Setting ACTUAL model of controller
- макет полностью игнорируется. Никаких ошибок или предупреждений не появляется. Что не так с настройкой макета?
Я также пытался с overload
и alias
, но они не работают, даже с:
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
В результате:
Mockery\Exception\RuntimeException: Could not load mock Controller, class already exists
Но я думаю, что это известная проблема.
Версии (устаревшая настройка, которая не поддерживает PHP 7):
PHP 5.6.40
PHPUnit 5.7.27
Насмешка 1.3.1