Тестирование 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();
}