I am trying to write a unit test to check the upload of files to a server in a Yii2 application using Codeception. There is a model Images:

<?php namespace common\models; use Yii; use yii\db\ActiveRecord; /** * This is the model class for table "images". * * @property integer $id * @property integer $good_id * @property string $path * @property string $image_name */ class Images extends ActiveRecord { public $img; /** * @inheritdoc */ public static function tableName() { return 'images'; } /** * @inheritdoc */ public function rules() { return [ [['good_id'], 'integer'], [['img'], 'file', 'extensions' => ['png', 'jpg', 'jpeg', 'gif'], 'maxSize' => Yii::$app->params['maxImageSize']], [['image_name', 'alt'], 'string', 'max' => 255] ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'good_id' => 'Good ID', 'image_name' => 'Image Name', ]; } public function getGood() { return $this->hasOne(Goods::className(),['good_id' => 'good_id'])->inverseOf('images'); } public static function deleteAll($condition = '', $params = []) { $files = self::find() ->select(['good_id', 'image_name']) ->where($condition) ->asArray() ->all(); foreach ($files as $file) { $file_name = Yii::$app->params['goodsImagePath'] . $file['good_id'] . '/' . $file['image_name']; if ($file['image_name'] && file_exists($file_name)) { unlink($file_name); } } return parent::deleteAll($condition, $params); } public function save($runValidation = true, $attributeNames = null) { $dir = Yii::$app->params['goodsImagePath'] . $this->good_id . '/'; if ($this->img) { if ($this->image_name) { $file = $dir . $this->image_name; if (file_exists($file)) { unlink($file); } } $this->image_name = uniqid() . '.' . $this->img->extension; $this->img->saveAs($dir . $this->image_name); } return parent::save($runValidation, $attributeNames); } } 

'goodsImagePath' parameter has the value '../../frontend/web/uploads/goods/'

You need to write a unit test to check if the file is saved on the server. If you try to create your UploadedFile class object both through the constructor and through getInstance() , the file will not be saved on the server. All due to the fact that the application has Post variable $_FILES , and in the test it is not defined. Most likely because of this, the file is not saved to the server.

An example of my unit test that does not work:

 public function testUploadFile() { $image = new UploadedFile([ 'name' => 'test_picture3.png', 'tempName' => \Yii::getAlias('@tests/codeception/common/unit/files/test_picture3.png'), 'type' => 'image/png', 'size' => 84.71 * 1024]);; $model = new Images([ 'id' => '2001', 'good_id' => 1001, 'image_name' => $image->name, 'img' => $image, ]); expect('File uploaded successfully', $model->validate())->true(); expect('File saved to server successfully', $model->save())->true(); $this->assertFileExists(Yii::getAlias('@app_configs/') . Yii::$app->params['goodsImagePath'] . $model->good_id . '/' . $model->image_name, "File should be exist in 'Uploads' directory "); } 

or the second option:

 public function testUploadCorrectFile() { $model = new Images([ 'id' => '2001', 'good_id' => 1001, 'image_name' => 'test_picture1.jpg', ]); $image = UploadedFile::getInstance($model, 'img'); $image->tempName = '' ; $image->name = 'test_picture1.jpg'; $image->tempName = \Yii::getAlias('@tests/codeception/common/unit/files/test_picture1.jpg'); $image->type = 'image/jpeg'; $image->size = 84.71 * 1024; $model->good_id = 1001; $model->id = '2001'; $model->image_name = $image->name; expect('File uploaded successfully', $model->validate())->true(); expect('File saved to server successfully', $model->save())->true(); $this->assertFileExists(Yii::getAlias('@app_configs/') . Yii::$app->params['goodsImagePath'] . $model->good_id . '/' . $model->image_name, "File should be exist in 'Uploads' directory "); } 

The file is not saved to the server. How to correctly check file loading in a unit test?

  • As an option: redefine the UploadedFile class for the test - Andrei Talanin

0