Я новичок в модульном тестировании и пытается реализовать первый набор тестов для контроллера индекса в приложении Zend Framework 1.
В этом контроллере у меня есть действие входа, которое использует Zend_Auth для проверки предоставленных учетных данных пользователя. Я не совсем понимаю, что это лучший способ проверить его:
Создайте отдельную конфигурацию тестовой базы данных. Перед выполнением любых тестов загрузите файл SQL с исходным состоянием базы данных и установите эту тестовую базу данных в качестве базы данных по умолчанию.
Переопределите (как-то) Zend_Auth так, чтобы он всегда возвращал предопределенный массив с информацией пользователя (или пустым массивом) и тестировал этот сценарий. Я нашел эту реализацию в Zend Framework 2, но нет для версии 1.
Я был бы признателен за любые советы и ссылки на проекты в ZF1, которые имеют модульное тестирование для аутентификации и функциональность, связанную с базой данных в целом.
UPD
Вот действие входа в Index Controller, которое я собираюсь проверить
public function loginAction()
{
$loginForm = new Form_Login();
$modelUser = new Model_User();
$formData = $this->getRequest()->getPost();
$flashMessenger = $this->_helper->getHelper('FlashMessenger');
if(!empty($formData)){
if($loginForm->isValid($formData)){
$authAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter());
$authAdapter->setTableName('user')
->setIdentityColumn('email')
->setCredentialColumn('password')
->setCredentialTreatment('MD5(?)');
$authAdapter->setIdentity($formData['form_email']);
$authAdapter->setCredential($formData['form_password']);
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if($result->isValid()) {
$userData = $authAdapter->getResultRowObject();
$modelUser->setTimestamp($userData->user_id);
$this->_processLoggedInUser($userData);
} else {
$loginForm->addError("Incorrect email/password");
}
}
}
//Retrieve Facebook App ID
$this->view->facebookAppId = Zend_Registry::get('facebookAppId');
$this->view->googleClientId = Zend_Registry::get('googleClientId');
$this->view->loginForm = $loginForm;
$this->view->userMsg = $flashMessenger->getMessages();
}
Итак, подумал я, возможно, я могу использовать Zend_Test_DbAdapter, установить его как адаптер по умолчанию и заставить его возвращать предопределенный набор данных?
Я обнаружил 2 способа работы с данными db во время модульных тестов:
1.
public function testStudentLogin()
{
$config = new Zend_Config_Ini(APPLICATION_PATH."/configs/application.ini", APPLICATION_ENV);
$testDatabaseConfig = $config->testDb;
$connection = Zend_Db::factory($testDatabaseConfig);
Zend_Db_Table::setDefaultAdapter($adapter);
$this->request->setMethod('POST');
$this->request->setPost(array('form_email' => 'student', 'form_password' => '123'));
$this->dispatch('/index/login');
$this->assertController('index');
$this->assertAction('login');
$this->assertRedirect('/index/student-professor');
}
Итак, здесь вы сохраняете учетные данные test db в application.ini. Затем вы инициализируете соединение с ним через адаптер и меняете Zend_Db_Table :: setDefaultAdapter.
2.
public function testStudentLogin()
{
$adapter = new Zend_Test_DbAdapter();
$stmt1Rows = array(array('user_id' => 1, 'email' => 'student', 'password' => '202cb962ac59075b964b07152d234b70', 'user_type' => 'consumer', 'zend_auth_credential_match' => 1));
$stmt1 = Zend_Test_DbStatement::createSelectStatement($stmt1Rows);
$adapter->appendStatementToStack($stmt1);
$this->request->setMethod('POST');
$this->request->setPost(array('form_email' => 'student', 'form_password' => '123'));
$this->dispatch('/index/login');
$this->assertController('index');
$this->assertAction('login');
$this->assertRedirect('/index/student-professor');
}
Здесь вы используете Zend_Test_DbAdapter, где вы можете предопределить, какие данные будут возвращены. Я думаю, что использование отдельной базы данных для целей тестирования делает ваш код более чистым, поэтому я, вероятно, буду использовать этот подход. Если у вас есть другие идеи/лучшие практики, дайте мне знать