Тестирование Phpunit с базой данных
Я пытаюсь немного сосредоточиться на модульном тестировании с помощью PHPunit.
Я нашел очень хороший учебник здесьhttp://blog.nickbelhomme.com/php/phpunit-training-course-for-free_282
но есть что-то, что я упускаю и еще не понимаю, как это сделать.
У меня есть пользовательский модуль, который поддерживает всю информацию о пользователях. И есть функция save, которая сохраняет пользователя в базе данных. Так что у меня есть функции testfunction
public function testCanCreateUser()
{
$userData = array(
'userName' => 'User1',
'firstName' => 'Joey',
'lastName' => 'Hendricks',
'email' => 'Joey@hendricks.com',
'password' => 'f$tfe8F'
);
$user = new Model_User($userData);
$user->save();
}
в первый раз, когда я буду запускать свой тест, это будет работать. Так как база данных пуста. Но когда я запускаю свои тесты во второй раз, он не будет работать, так как моя система не позволяет одному и тому же пользователю дважды в БД. Поэтому, чтобы сделать это, я должен воссоздать свою testdatabase каждый раз, прежде чем запускать свои тесты. Как лучше всего это сделать? Или эту проблему нужно решать по-другому?
Tnx.
3 ответов
Если вы хотите проверить свою бизнес-логику: издеваться над классом базы данных и возвращать поддельные данные
Если вы хотите проверить класс, который запускает операторы sql (и imho вы можете проверить это тоже, так как я хочу знать, хорошо ли работает мой код с реальной БД в бэкэнде) это становится немного сложным, но есть способы сделать это:
использование setUp () и tearDown() для получения согласованного состояния для данных перед запуском ваши тесты (imho)-отличный способ написать управляемые БД unittests. Это может раздражать, чтобы написать много пользовательских sql вручную.
чтобы сделать вашу жизнь немного проще, вы можете посмотреть в разделе расширение DbUnit и посмотреть, работает ли это для вашего приложения.
Если вы действительно хотите погрузиться в Unittesting взаимодействия баз данных лучшее чтение по этому вопросу (imho) глава о db-unittesting в Себастьян Бергманн phpqa книга.
может ли ваше приложение разрешить пользовательское имя базы данных и автоматическую настройку всех таблиц, также можно настроить БД один раз с большим количеством testdata и использовать эти данные во всех ваших тестах. Вы можете быть осторожны, так что хотя один тест не полагается на данные, написанные другим.
выполнить тесты с другой копией базы данных, которая пуста и / или очищена в setUp()
или tearDown()
методы, но будьте осторожны, чтобы не сделать то, что гитхаб сделал.
если вы используете хорошую базу данных (т. е. не MySQL с таблицами MyISAM) , вы можете обернуть тест в транзакцию и откатить ее после теста:
function setUp() { $this->db->exec("BEGIN"); }
function tearDown() { $this->db->exec("ROLLBACK"); }
недостатком является то, что вы не можете тестировать код, который использует транзакции (если вы не абстрагируете это и не эмулируете с помощью savepoints, но это сомнительный.)
В идеале вы должны использовать инъекцию зависимостей и запускать тесты на поддельном классе базы данных:
$fakedb = new DatabaseThatDoesntReallySaveThings();
$user = new Model_User($fakedb, $userData);
$user->save();
$this->assertTrue($fakedb->wasAskedToSaveUser());
Я думаю, вы можете использовать tearDown()
метод очистки сохраненных данных.
protected $_user;
public function testCanCreateUser()
{
...
$this->_user = new Model_User($userData);
$this->_user->save();
}
public function tearDown()
{
$this->_user->delete();
}