• Чистые тесты на PHP и PHPUnit
    0

    Я полностью согласен — RecordStorage нужно покрыть интеграционным тестом, чтобы гарантировать его работу, как ожидается. Просто с тем кодом, где использовался private, вам нужна магия PHP, чтобы добраться до private, нам требуется знание черного ящика, тела функции, знания о её реализации...


    Никогда не тестируйте защищённые/приватные методы
    Основная причина: они влияют на то, как мы тестируем функции, определяя сигнатуру поведения: при таком-то условии, когда я ввожу А, то ожидаю получить Б. Приватные/защищённые методы не являются частью сигнатур функций.

    А с кодом, который без private, мы проверяем результат RecordStorage::load($id) — подсовывая в constructor нужные нам состояния $cache и $storage, проверяем возвращаемый Record — никакой магии и тест будет читаться просто:


    Дано RecordStorage и когда $cache и $storage такие-то, тогда RecordStorage::load($id) возвращает такой-то Record.


    При private тестируется: будет ли второй раз при запросе к load отрабатывать кэш. А в третий, а в четвёртый — уверены?
    Без private тестируется:


    • будет ли возвращён по id ожидаемый Record, который в cache, если он там имеется
    • будет ли возвращён по id ожидаемый Record, который в storage если в cache его нет.
  • Чистые тесты на PHP и PHPUnit
    0

    Тут дело в том, что классу RecordStorage позволительно очень многое. По сути он создавался как сервис получения данных из хранилища.


    В качестве хранилища у вас выступает doLoad() или $this->db->select('...') или т.д., по хорошему этот код должен быть в отдельном классе.


    Сейчас за хранилище отвечает Сервис API получения данных из хранилища. Это и есть причина того, что есть потребность тестировать RecordStorage:load(). А если переписать код как указано ниже, то и тестировать нечего.


    final class RecordStorage {
    
        /** Cache backend */
        private $cache;
        /** Cache backend */
        private $storage;
    
        public function load($id): Record
        {
            if ($record = $this->cache->get($id)) { // протестировано отдельным тестом
                return $record;
            }
            $record = $this->storage->dataById($id); // протестировано отдельным тестом
            $this->cache->set($id, $record); // протестировано отдельным тестом
            return $record;
        }
    }

    Пункт "Никогда не тестируйте защищённые/приватные методы", да и вообще рекомендации из статьи в целом хороши тем, что заставляют думать и писать "чистый код".

  • Чистые тесты на PHP и PHPUnit
    0

    [удалено] не туда..

  • Чистые тесты на PHP и PHPUnit
    0

    По хорошему:


    • $this->cache->get($id) нужно протестировать отдельным тестом.
    • $this->cache->set($id, $record); тоже нужно протестировать отдельным тестом.
    • doLoad() должен быть публичным, с вынесением в отдельный класс — тоже должен быть протестирован на граничные случаи.

    Тогда RecordStorage:load() тестировать нет необходимости. RecordStorage превратиться сервис, который получает данные от протестированных компонентов и делегирует их в другие протестированные компоненты.


    Так что для пункта 5. Никогда не тестируйте защищённые/приватные методы исключений не бывает ;)

  • Ненужные HTTP-заголовки
    +1
    Не ожидал, что в 2018 году придётся упоминать заголовок Pragma...

    Предполагаю, что одна из причин, по которой он в топе — это отправка этого заголовка по умолчанию в PHP при старте сессии (Pragma: no-cache).
    http://php.net/manual/ru/function.session-cache-limiter.php

  • PHP-Дайджест № 108 – свежие новости, материалы и инструменты (24 апреля – 14 мая 2017)
    0

    Там рождается ещё один слоник.

  • Hello, Шульте
    +1

    Когда лень :/


    var speed = 1000;
    var clickEvent = new MouseEvent("click");
    var elements = [].slice.call(document.getElementsByClassName("cell"));
    elements.sort(function(a, b){return a.textContent - b.textContent;});
    
    for(var i = 0; i < elements.length; i++) {  
        setTimeout(function(element){element.dispatchEvent(clickEvent);}, i*speed, elements[i]);
    }
  • Вышел релиз Laravel 5.3
    0

    Первый вариант кстати тоже, он заменяется на:


    'rules' => [
           ['class' => 'yii\rest\UrlRule', 'controller' => ['api/v1/users', /**...*/ ]],
    ]
  • Yii 2.0.8
    0

    Ну и демо данные набросать ещё можно, по аналогии с этим PR:


    php yii fixture "User"
  • Yii 2.0.8
    +2

    Мне вот очень зашло:


    php yii migrate/create create_user --fields="username:string(255):notNull(),email:string():notNull()"
    // проверяем, поправляем код миграции в файле
    php yii migrate 
    php yii gii/model --modelClass="User" --tableName="user" --ns="backend\models"
    // поправляем, проверяем код модели в файле
    php yii gii/crud --controllerClass="backend\controllers\UserController" --modelClass="backend\models\User"
    // Теперь осталось код чуточку подправить и показать PM ;) 

    Скелет CRUD приложения для вашей модельки готов, который вполне работает. При этом не надо было запускать браузер и "программировать мышкой".