Тестовая вставка базы данных с использованием Symfony
Всем доброго дня,
В последние несколько дней я много занимался разработкой на основе тестов и решил, что мне тоже нужно этому научиться. Хотя я не могу понять, как это сделать точно.
Мой проект зависит от платформы и доктрины Symfony2.1.6, поэтому у меня есть несколько таблиц базы данных, которые необходимо заполнить.
Книга (1, n) - (0,n) Жанр
Теперь, если я хочу вставить жанровую запись, мне сначала нужно написать тест, чтобы убедиться, что все вставляется так, как должно (или я ошибаюсь?)
Проблема сейчас в том, что я не знаю, как получить доступ к своей базе данных, поскольку она управляется платформой.
Единственное, что я смог найти, это с помощью LiipFunctionalTestBundle https://github.com/liip/LiipFunctionalTestBundle , который создает и восстанавливает временную базу данных каждый раз, когда я запускаю тест. Я настроил все в соответствии с Инструкциями.
Редактировать: Мое приложение/конфигурация/config_test.yml выглядит вот так сейчас:
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.filesystem
liip_functional_test: ~
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
liip_functional_test:
cache_sqlite_db: true
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_sqlite
path: %kernel.cache_dir%/test.db
Итак, теперь у меня есть класс GenreTest:
У Liip нет документации, поэтому я просто попробовал такой подход.
use Liip\FunctionalTestBundle\Test\WebTestCase;
class GenreTest extends WebTestCase {
public function testInsert() {
$container = $this->getContainer();
$registry = $container->get('doctrine');
$em = $registry->getEntityManager(null);
$genre = new Genre();
$genre->setName("testGenre");
$em->persist($genre);
$em->flush();
$result = $em->createQuery("SELECT g FROM QkprodMangressBundle:Genre g ".
"WHERE g.name = :name")
->setParameter("name", $genre->getName())
->getResult();
$this->assertEqual($result[0]->getName(), $genre->getName());
}
}
Веб-сайт Phpunit -c/
Исключение PDO: не удалось найти драйвер /.../Мангресс/поставщик/доктрина/dbal/библиотека/Доктрина/DBAL/Драйвер/pdoconnection.php:36 /.../Mangress/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php :60 /.../Мангресс/поставщик/доктрина/dbal/библиотека/Доктрина/DBAL/Подключение.php:350 /.../Мангресс/поставщик/доктрина/dbal/библиотека/Доктрина/DBAL/Подключение.php:949 /.../Мангресс/поставщик/доктрина/orm/библиотека/Доктрина/ORM/UnitOfWork.php:306 /.../Мангресс/поставщик/доктрина/orm/библиотека/Доктрина/ORM/EntityManager.php:355 /.../Мангресс/приложение/кэш/тест/jms_diextra/доктрина/entitymanager_510128d0a5878.ph р:362 /.../Mangress/src/Qkprod/Mangressbundle/Тесты/Сущность/genretest.php:27 НЕУДАЧИ! Тесты: 3, Утверждения: 1, Ошибки: 1.
Главный вопрос, который у меня возникает, заключается в том... как мне проверить что-то в этом роде? Или я даже проверяю связь с базой данных? Подделка связи с базой данных с помощью пользовательской реализации не кажется мне хорошей идеей, потому что она также будет использовать ORM и доктрину в производственной среде.
Извините.. здесь оказался небольшой роман.
3 answers
Я почти полностью решил свою проблему с помощью:
-
Установите драйверы, необходимые для связи с бд ;)
Драйвер PDO_SQLITE отсутствует.. что делать?sudo apt-get install php5-sqlite
Воссоздавайте схему при каждом запуске теста
https://stackoverflow.com/a/10463614/1177024
Это тестирование моего класса по базе данных
namespace Qkprod\MangressBundle\Entity;
use Qkprod\MangressBundle\Entity\Genre;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
private $em;
/**
* Sets up environment for testing
* Regenerates Database schema before every test-run
*/
public function setUp() {
static::$kernel = static::createKernel();
static::$kernel -> boot();
$this -> em = static::$kernel->getContainer()
->get('doctrine')
->getEntityManager();
$this->regenerateSchema();
}
protected function tearDown() {
parent::tearDown();
$this -> em -> close();
}
/**
* Drops current schema and creates a brand new one
*/
protected function regenerateSchema() {
$metadatas = $this->em->getMetadataFactory()->getAllMetadata();
if (!empty($metadatas)) {
$tool = new \Doctrine\ORM\Tools\SchemaTool($this->em);
$tool -> dropSchema($metadatas);
$tool -> createSchema($metadatas);
}
}
public function testInsert() {
$genre = new Genre();
$genre -> setName("testGenre");
$this -> em -> persist($genre);
$this -> em -> flush();
$result = $this -> em
-> createQuery("SELECT g "
. " FROM QkprodMangressBundle:Genre g "
. " WHERE g.name = :name")
-> setParameter("name", $genre -> getName())
-> getResult();
$this -> assertEquals($result[0] -> getName(), $genre -> getName());
}
}
Не удалось заставить LiipBundle работать, но вы можете увеличить невероятно ускорьте работу, настроив symfony для сохранения базы данных sqlite в памяти вместо файловой системы.
https://stackoverflow.com/a/10460139/1177024
# app/config/config_test
doctrine:
dbal:
driver: pdo_sqlite
path: :memory:
memory: true
Или, может быть, создайте схему только один раз и вместо того, чтобы создавать ее заново, просто замените базу данных новой резервной копией.
Я надеюсь, что это сократит поиск некоторых людей, у которых такая же проблема! Спасибо всем, кто помогал мне на этом пути:) Ты великолепен!
Попробуйте еще раз с помощью документов symfony.
Http://symfony.com/doc/2.0/cookbook/testing/doctrine.html
Или вы можете изменить свой конструктор тестового набора с помощью:
public function __construct()
{
$kernelNameClass = $this->getKernelClass();
$kernel = new $kernelNameClass('test', true);
$kernel->boot();
$this->em = $kernel->getContainer()->get('doctrine.orm.entity_manager');
}
Затем вы будете использовать
$this->em->createQuery($dql);
И т.д.
Вы можете подключиться внутри метода setUp()
:
/**
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* {@inheritDoc}
*/
public function setUp()
{
static::$kernel = static::createKernel();
static::$kernel->boot();
$this->em = static::$kernel->getContainer()
->get('doctrine')
->getManager()
;
}
Здесь пример из книги Symfony 2.1