我有一个 DoctorsController
,它有一个 store
方法。我正在测试这个方法,我希望我的模型不要在测试环境中INSERT
他们的数据。所以我在我的 Controller 和我的 Controller 中使用了 DB::beginTransaction
, DB::rollback()
, DB::commit()
方法防止 INSERT
查询的测试方法。我的问题是 => 数据库在我的测试运行时有记录。我不希望在测试期间有任何 INSERTS
。
我的测试代码:
public function testStoreMethod()
{
/*
* Test when validation fails
*/
$data = include_once('DoctorsControllerFormData.php');
foreach($data as $item){
DB::beginTransaction();
$response = $this->call('POST', 'doctors', $item);
$this->assertResponseStatus(400, "response's HTTP code is not 400 : " . implode('\n',array_flatten($item)));
Log::debug($response);
DB::rollback();
}
}
我的 DoctorsController 代码片段:(调用 UsersController 的
store
方法)
public function store()
{
//some code
DB::beginTransaction();
try{
/*
* User Creation
*/
$user = new UsersController();
$user->setResource('doctor');
$userID = $user->store();
//some other code
}catch (InputValidationFailedException $e){
DB::rollback();
return Response::make(json_encode(array('error' => $e->getErrors())), \Symfony\Component\HttpFoundation\Response::HTTP_BAD_REQUEST);
}catch(Exception $e){
Log::error('Server Error at DoctorsController');
DB::rollback();
App::abort(500, $e->getMessage());
}
}
我的 UsersController 代码片段:
public function store()
{
$user = new User;
try{
$inputs = Input::all();
Log::info("input Data" . implode("\n", array_flatten(Input::all())));
/*
* User Creation
*/
$v = Validator::make(
$inputs,
User::$rules
);
if($v->fails()) {
Log::error('Validation Failed! ' . implode("\n", array_flatten($v->messages()->all())));
throw new InputValidationFailedException($v);
}
$user->fname = Input::get('fname');//set first name
$user->lname = Input::get('lname');//set last name
$user->email = Input::get('email');//set email
$user->cell = Input::get('cell');//set cell number
$user->password = Hash::make(Input::get('password'));//set password
$user->gender_id = Input::get('gender') == 'm' ? 1 : 0;//set gender
$user->is_active = 0;//set activation status
$user->role_id = ($this->resource == 'doctor') ? 1 : 2;
$user->activation_time = 0;//set activation time default to 0
$user->expiration_time = 0;//set expiration time default to 0
//insert the user into DB
$user->save();
}catch (InputValidationFailedException $e){
Log::info('User Validation Failed! ' . implode("\n", array_flatten($e->getErrors())));
throw $e;
}catch (Exception $e){
Log::error('Server Error at UsersController!');
throw $e;
}
return $user->id;
}
感谢您的帮助。
最佳答案
如果您在 Controller 中提交更改,则测试中的 DB:rollback
无法撤消这些更改,因为事务已在那里完成。话虽这么说,你真的不应该使用同一个数据库进行测试,就像你用于开发一样。 Laravel 有 Migrations & Seeding你可以用它来 refresh and reseed每次运行测试时都有专用的测试数据库。
如果可能,我建议使用内存 数据库来避免完全写入持久性数据库,如下面链接的视频中所述:
关于php - 无法在 laravel 的 Controller 中使用数据库事务(DB::beginTransaction),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29947207/