【问题标题】:Can't use DB Transactions in Controllers in laravel (DB::beginTransaction)不能在 laravel 的控制器中使用数据库事务(DB::beginTransaction)
【发布时间】:2015-04-29 14:49:06
【问题描述】:

我有一个DoctorsController,它有一个store 方法。我正在测试这种方法,我希望我的 Models 在测试环境中不要INSERT 他们的数据。所以我在我的控制器中使用DB::beginTransactionDB::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();
    }
}

My DoctorsController 代码 sn-p:(调用 UsersController'sstore 方法)

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 代码 sn-p :

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;
}

感谢您的帮助。

【问题讨论】:

  • 您的数据库是 innoDB 还是 myisammyisam 不知道交易。
  • @Daan 非常感谢您提供这些信息。我在这里受苦了。

标签: php mysql unit-testing laravel testing


【解决方案1】:

如果您在控制器中提交更改,那么测试中的 DB:rollback 无法撤消这些更改,因为事务已在此处完成。话虽如此,您不应该真正使用相同的数据库进行测试,就像您用于开发一样。 Laravel 有 Migrations & Seeding,你可以在任何时候运行测试时使用它来 refresh and reseed 一个专用的测试数据库。

如果可能,我建议使用内存中数据库来避免完全写入持久性数据库,如下面链接的视频所述:

Laracasts - Test DBs in Memory

【讨论】:

猜你喜欢
  • 2017-11-09
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 2013-04-29
  • 2019-12-22
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多