I have a DoctorsController
which has a store
method. I'm testing this method and I want my Models not to INSERT
their data in testing environment. So I'm using DB::beginTransaction
, DB::rollback()
, DB::commit()
methods in my controllers and my testing method to prevent INSERT
queries. my problem is => Database is having records while my tests are running. I don't want any INSERTS
during tests.
My test code :
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('
',array_flatten($item)));
Log::debug($response);
DB::rollback();
}
}
My DoctorsController code snippet : (which calls UsersController's
store
method)
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());
}
}
My UsersController code snippet :
public function store()
{
$user = new User;
try{
$inputs = Input::all();
Log::info("input Data" . implode("
", array_flatten(Input::all())));
/*
* User Creation
*/
$v = Validator::make(
$inputs,
User::$rules
);
if($v->fails()) {
Log::error('Validation Failed! ' . implode("
", 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("
", array_flatten($e->getErrors())));
throw $e;
}catch (Exception $e){
Log::error('Server Error at UsersController!');
throw $e;
}
return $user->id;
}
Thanks for your help.
If you're commiting the changes in your controller, then the DB:rollback
in your test can't undo those changes because the transaction was finished there. That being said, you shouldn't really be using the the same database for testing, as you are for development. Laravel has Migrations & Seeding which you can use to refresh and reseed a dedicated testing database any time you run your tests.
If possible, I suggest using an in memory database to avoid writing to a persistent database altogether, as explained in the video linked below: