dpcj32769 2015-04-29 06:49
浏览 536
已采纳

不能在laravel中使用控制器中的DB事务(DB :: beginTransaction)

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.

展开全部

  • 写回答

1条回答 默认 最新

  • douzong3599 2015-04-29 08:05
    关注

    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:

    Laracasts - Test DBs in Memory

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部