У меня есть сайт, которому нужно время от времени подключаться к вторичной базе данных. У меня все это работает правильно, но, конечно, мне нужно, чтобы он был тестируемым.
Соединения со второй базой данных должны быть транзакционными, поэтому мне нужен тест, имитирующий неудачную транзакцию.
Так что в моей работе у меня есть код, подобный следующему ($ this-> dbConnection - это Illuminates \ Database \ Connection или значение NULL, переданное в работу)
$connection = $this->dbConnection ? $this->dbConnection : DB::connection('conn2');
try {
$connection->beginTransaction();
//snip
$connection->table('table1')->insert($data);
$id = $connection->table('table1')->select('id')->value('id');
//snip2
$connection->table('table2')->insert($data2);
$connection->commit();
} catch (Exception $e) {
$connection->rollback();
throw ($e);
}
Мне нужен тестовый пример, который вызывает последний запрос завершается неудачно (например, исключение выдается в snip2), так что я могу подтвердить, что была выполнена откат всей транзакции (т. е. $ data не найден в table1).
Есть ли способ смоделировать мой объект Connection так, что любая другая команда выполняется нормально и попадает в тестирующую базу данных Sqlite, но таблица ('table2') завершается неудачно?
Редактировать: вот временный интервал, который я вычислил. Это выглядит не элегантно.
Пользовательский тип исключения, поэтому я могу быть уверен, что произойдет правильный сбой
class MySpecialException extends Exception {}
Уродливая фиктивная оболочка. Это бит, который меня не волнует.
class MockConnectionWrapper extends \Illuminate\Database\Connection
{
protected $realConnection;
public function __construct($realConnection)
{
$this->realConnection = $realConnection;
}
public function table($table, $as = null) {
if ($table == 'table2') { throw new MySpecialException('hard-coded error text'); }
return $this->realConnection->table($table, $as);
}
public function reconnect() { return $this->realConnection->reconnect(); }
public function beginTransaction() { return $this->realConnection->beginTransaction(); }
public function rollback($toLevel = NULL) { return $this->realConnection->rollback($toLevel); }
}
Тогда тест содержит
$mock = new MockConnectionWrapper(DB::connection('conn2'));
$job = new MyJob($mock);
try {
$job->handle();
} catch (MySpecialException $e) {
$this->assertEquals($e->getMessage(), 'hard-coded error text');
}
$this->assertDatabaseMissing('table1', $data, 'conn2');