Как можно проверить сохранение файлов на сервер в Unit-тесте?

Всё про тестирование в Yii 2.0
Ответить
Mubat
Сообщения: 7
Зарегистрирован: 2016.08.14, 15:55

Как можно проверить сохранение файлов на сервер в Unit-тесте?

Сообщение Mubat »

Добрый день.
Пытаюсь написать unit-тест для проверки загрузки файлов на сервер в Yii2 приложении используя Codeception. Есть модель 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' имеет значение  '../../frontend/web/uploads/goods/'

Нужно написать Unit-тест для проверки сохранения файла на сервер. Если пытаться создать свой объект класса UploadedFile (как через конструктор, так и через getInstance()) то файл не сохранится на сервере. Предполагаю, что в тесте не определена post переменная $_FILES. Скорее всего из-за этого сам файл не сохраняется на сервер.

В обоих случаях файл не сохраняется на сервер. Как правильно проверять загрузку файлов в unit-тесте?

Пример моего unit-теста, который не работает:

Код: Выделить всё

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 ");

}
второй вариант unit-теста:

Код: Выделить всё

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 ");
}
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Как можно проверить сохранение файлов на сервер в Unit-тесте?

Сообщение ElisDN »

Добавьте в _bootstrap.php:

Код: Выделить всё

namespace yii\web {
    function move_uploaded_file($from, $to) {
        rename($from, $to);
    }
    function is_uploaded_file($file) {
        return true;
    }
} 
Ответить