Задонатить и смотреть →
Открой безлимитный доступ к 100+ полезных скринкастов и получай скидки на все предстоящие мероприятия

Смена пароля и тесты с зависимостями

Реализация команды установки нового пароля с проверкой текущего. Инъекция сервисов в метод. Тестирование зависимых объектов. Стабы и моки.

  • 00:00:38 - Постановка задачи
  • 00:02:52 - Команда смены пароля
  • 00:03:35 - Подход с внешними проверками
  • 00:05:36 - Инкапсуляция операции в сущности
  • 00:06:56 - Unit-тесты для метода changePassword
  • 00:07:39 - Тестовая реализация для интерфейса
  • 00:08:23 - Заглушка для класса
  • 00:09:17 - Механика создания стабов в PHPUnit
  • 00:12:50 - Если бы тестировали команды
  • 00:14:53 - Отличие моков от стабов
  • 00:17:40 - Вынос создания стаба в метод
  • 00:18:11 - Тест для некорректного пароля
  • 00:18:33 - Тест для пользователя из соцсети
  • 00:19:32 - Доработка UserBuilder
  • 00:21:51 - Реализация метода changePassword
  • 00:22:43 - Оптимизация метода сброса пароля
  • 00:23:14 - Необходимость проверок в API
Скрытый контент (код, слайды, ...) для подписчиков. Открыть →
Дмитрий Елисеев
elisdn.ru
Комментарии (13)
Arunas

Спасибо.

Ответить
Arunas

падумал: нет ли возможность взять какой то кмпонент аутентификации из напр. Симфони и присвоит здесь как то?...

Ответить
Дмитрий Елисеев

Да, возможно. Symfony-компоненты как раз могут использоваться сами по себе в любом проекте.

Ответить
Sergei

Разница между стабом и моком понятно, но есть еще професи, и оно выглядит также как и стаб. Тогда в чем разница? Спасибо

Ответить
Дмитрий Елисеев

Prophecy - это отдельный фреймворк.

В его описании есть примеры, как с его помощью делать стабы и моки.

Ответить
Dmitriy

Много где слышал, что хорошей практикой является создание собственных классов исключений. Почему вы не практикуете это?

Ответить
Дмитрий Елисеев

Это удобно если есть необходимость их по-разному отлавливать и обрабатывать. Например, если мы пишем клиент для API, то в нём есть смысл делать свои отдельные ConnectionException и ResponseException, чтобы дать возможность отлавливать их разными блоками catch {}.

Или чтобы в тех же тестах или переводов указывать имена классов вместо текста:

$this->expectException(ResettingNotRequestedException::class);

В нашем же случае мы все доменные исключения будем отлавливать и отображать одинаково. Так что особой пользы добавление куч классов исключений нам не принесёт.

Ответить
Артем Астапов

UserBuilder не настроит active статус у юзера из соцсети, возврат раньше происходит.

Ответить
Евгений

Добрый день, подскажите если не трудно, какое лучшее решение для теста сущностей с индефикатором через обычный автоинкрементный id ? мне подход uuid понравился, но команду не всегда убедишь в продакшене такое использовать, а тесты писать хочется)

Ответить
Дмитрий Елисеев

Если работаем с PostgreSQL, то можно сделать отдельную секвенцию и через репозиторий доставать инкрементный идентификатор из неё:

class TaskRepository
{
    ...

    public function nextId(): Id
    {
        return new Id((int)$this->db->query('SELECT nextval(\'tasks_seq\')')->fetchColumn());
    }
}

и подставлять при создании этот числовой id:

$task = new Task(
    $this->tasks->nextId(),
    $command->name
);

То есть сделать числовой идентификатор и заполнять из секвенции.

А в MySQL можно эмулировать секвенцию отдельной таблицей с одним полем:

CREATE TABLE tasks_seq (
  id INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)

и в репозитории делать вставку туда записи с id=NULL и брать lastInsertId.

Либо смириться и id не тестировать.

Ответить
Евгений

понял, спасибо за ответ

Ответить
Дмитрий

Можно рефлексию в юнит тестах заюзать для принудительного проставления ид в сущности.

Ответить
Дмитрий Елисеев

Нет никакой пользы делать это только в тестах.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий

Или войти через:

Google
GitHub
Yandex
MailRu