CakePHP4 PHPUnit测试save操作丢失auto_increment id报错排查
CakePHP4控制器PHPUnit测试中save方法后id自增失效问题
问题说明
我正在使用PHPUnit进行CakePHP4控制器测试,调用save方法后id的auto_increment属性失效。该控制器在实际应用中运行正常,但测试环境下出现报错。
- 保存前:表的id字段为自增主键,状态正常
- 保存后:id字段的自增属性丢失,触发数据库报错
测试代码
public function testAdd(): void { $this->session([ 'Auth' => [ 'id' => 1, 'DNI_CIF' => '22175395Z', 'name' => 'Prueba', 'lastname' => 'Prueba Prueba', 'username' => 'Pruebatesting', 'password' => 'prueba', 'email' => 'prueba@gmail.com', 'phone' => '639087621', 'role' => 'admin', 'addres_id' => 1 ] ]); $this->get('animal/add'); $this->assertResponseOk(); $data=[ 'id' => 1, 'name' => 'AñadirAnimal', 'image' => '', 'specie' => 'dog', 'chip' => 'no', 'sex' => 'intact_male', 'race' => 'cat', 'age' => 1, 'information' => 'Es un animal.', 'state' => 'sick', 'animal_shelter' => [ 'id' => 1, 'start_date' => '2022-11-03 10:47:38', 'end_date' => '2022-11-03 10:47:38', 'user_id' => 1, 'animal_id' => 1 ] ]; $this->enableCsrfToken(); $this->post('animal/add',$data); $this->assertResponseOk(); }
控制器代码
public function add() { $animal = $this->Animal->newEmptyEntity(); if ($this->request->is('post')) { $animal = $this->Animal->patchEntity($animal, $this->request->getData()); if(!$animal->getErrors){ $image = $this->request->getData('image_file'); if($image !=NULL){ $name = $image->getClientFilename(); } if( !is_dir(WWW_ROOT.'img'.DS.'animal-img') ){ mkdir(WWW_ROOT.'img'.DS.'animal-img',0775); if($name){ $targetPath = WWW_ROOT.'img'.DS.'animal-img'.DS.$name; $image->moveTo($targetPath); $animal->image = 'animal-img/'.$name; } } if ($this->Animal->save($animal)) { $this->Flash->success(__('El animal se ha añadido.')); return $this->redirect(['action' => 'index']); } } $this->Flash->error(__('El animal no se ha podido añadir, por favor intentalo de nuevo')); } $allUsers = $this->getTableLocator()->get('User'); $user = $allUsers->find('list', ['limit' => 200])->all(); $this->set(compact('animal','user')); }
报错信息
1) App\Test\TestCase\Controller\AnimalControllerTest::testAdd Possibly related to PDOException: "SQLSTATE[HY000]: General error: 1364 Field 'id' doesn't have a default value" … Failed asserting that 500 is between 200 and 204.
问题原因及修复方案
1. 测试数据手动传入id的冲突
测试代码中手动设置了'id' => 1,CakePHP新增记录时若传入id,会优先使用该值而非依赖自增逻辑。测试环境中可能该id已存在,或手动传入id干扰了ORM的自增序列管理,导致后续自增属性异常。生产环境用户提交不会传入id,因此无此问题。
修复:移除测试$data中的'id' => 1,让ORM自动生成自增id。
2. 控制器错误检查的语法错误
控制器中if(!$animal->getErrors)是错误写法,getErrors是方法,需调用执行:if(!$animal->getErrors())。该错误会导致即使实体验证失败,代码仍会执行到save步骤,触发数据库异常。
修复:修正控制器中的条件判断为if(!$animal->getErrors())。
3. 测试数据库事务回滚的影响
PHPUnit默认开启事务回滚,测试结束后回滚操作,但手动插入id可能导致自增计数器未被正确重置,或回滚时影响了自增属性状态。
修复:在测试方法开头重置自增序列(根据实际表名调整):
$this->Animal->query()->execute('ALTER TABLE animals AUTO_INCREMENT = 1;');
4. 测试环境表结构一致性
确认测试数据库的表结构与生产环境一致,确保id字段确实设置为自增主键。
内容的提问来源于stack exchange,提问作者Iria
相关产品推荐
相关产品推荐

