Testování modelů se závislostmi
- zachrdlapetr
- Člen | 49
Potřebuji trochu nakopnout ohledně testování modelů, ale prakticky jde o jakoukoliv jinou třídu se závislostmi.
Mám následující tester s modelem bez závislosti a tohle jede normálně.
Tester
namespace Test;
use Nette;
use Tester\Assert;
$container = require './bootstrap.php';
class Test extends \Tester\TestCase {
public $container;
public $array;
public function __construct(\Nette\DI\Container $container) {
$this->container = $container;
$this->array = $container->getByType('\App\Model\Utilities\NecoModel');
}
public function testTestu() {
Assert::type('array', $this->array->get(['aaa']));
}
}
$testcase = new Test($container);
$testcase->run();
Model bez závislosti
namespace App\Model\Utilities;
class NecoModel {
public function get($array) {
return $array;
}
}
Ale…
Pak mám model se závislostí, třeba na databázi. A tato se mi nedaří dostat do testu uvedeného výše. Pomůžete mi někdo prosím?
Model se závislostí na db
namespace App\Model\Utilities;
class NecoModel {
public $db;
public function __construct(\Nette\Database\Context $db) {
$this->db = $db;
}
public function get($array) {
return $array;
}
}
- kocourPB
- Člen | 47
Ahoj,
pokial chces testovat testovat nejaku classu z modelu, ktora obsahuje zavislosti na inej classe (viz. v tvojom pripade \Nette\Database\Context) musis si tuto classu najskor namockovat. Hodi sa na to napr. Mockery .. example: http://docs.mockery.io/…example.html
- kocourPB
- Člen | 47
priklad ako by to asi mohlo vyzerat:
<?php
namespace Test;
use Nette;
use Tester\Assert;
class Test extends \Tester\TestCase {
public function testArray() {
$dbContextMock = \Mockery::mock('Context');
$necoModel = new \App\Model\Utilities\NecoModel($dbContextMock);
Assert::type('array', $this->array->get(['aaa']));
}
}
(new Test())->run();
Editoval kocourPB (26. 4. 2019 13:27)
- David Matějka
- Moderator | 6445
Pokud píšeš unit testy, tak jak píše @kocourPB
Pokud však chceš psát integrační testy včetně databáze, tak to, co píšeš, by mělo fungovat. co konkrétně znamená, že se ti to nedaří? ja vytváříš ten container?
- zachrdlapetr
- Člen | 49
kocourPB napsal(a):
super. díky za tip. mockery jsem neznal. prostuduji. funguje to skvěle.
- zachrdlapetr
- Člen | 49
David Matějka napsal(a):
Pokud píšeš unit testy, tak jak píše @kocourPB
Pokud však chceš psát integrační testy včetně databáze, tak to, co píšeš, by mělo fungovat. co konkrétně znamená, že se ti to nedaří? ja vytváříš ten container?
bohužel měl jsem problém v testu vložit tam Nette\Database\Context nějak elegantně, protože ta třída sama o sobě vyžaduje další závislost. Mockery to vyřešila. Nebo existuje i jiný způsob jak vložit databázi do testArray() níže?
public function testArray() {
$db = \Mockery::mock('Nette\Database\Context');
$dbc = \Mockery::mock('Nette\Database\Connection');
$arrayModel = new \App\Model\Utilities\ArrayModel($db, $dbc);
Assert::type('array', $arrayModel->trimArrayRecursively(['aaa']));
}
container mám klasiku. cache a log ukládání zvlášť.
require '../vendor/autoload.php';
$configurator = new Nette\Configurator();
$configurator->enableTracy(__DIR__. '/../log_tester');
$configurator->setTimeZone('Europe/Prague');
$configurator->setTempDirectory('../temp_tester');
$configurator->createRobotLoader()
->addDirectory('../app')
->register();
$configurator->addConfig('../app/config/config.neon');
$configurator->addConfig('../app/config/config.local.neon');
$container = $configurator->createContainer();
return $container;