@smple

Как тестировать несколько реализаций одного интерфейса в phpunit?

Добрый день возникла следующая ситуация.
Допустим есть произвольные интерфейсы I1 и I2.
Есть 3 объекта: O1 реализует I1, O2 реализует I2 и O3 реализует I1 и I2 (знаю что плохо и что у объекта должна быть единая ответственность).

Хочется чтобы было место с описанием тестов для I1 и I2 и чтобы эти тесты можно было подключить при тестирование объектах O1, O2 и O3.

Я рассматривал варианты для интерфейсов создавать абстрактный класс который наследуется от phpunit test case но тогда объект O3 нельзя протестировать (множественное наследование).

Наиболее приближенный вариант это для I1 и I2 создать трейт в котором будет описываться одинаковое поведение для всех кто реализует данный интерфейс, а внутри тест кейсов уже подключаются нужные трейты (в зависимости от того что они реализуют), но тогда нет никакого автокомплита в ide.

у меня есть ещё несколько идей но все они кажутся костылями.

Возможно есть другие методы как протестировать подобное?

Может кто поделится лучшими практиками.

В качестве примера
<?php

interface MagicIntreface
{
    /**
     * @param $name
     * @return mixed
     * @throws InvalidArgumentException if name not found or not string
     */
    public function get($name);
}

class A implements MagicIntreface
{
    public function get($name)
    {
        if (!is_string($name)) {
            throw new RuntimeException('Invalid name');
        }
        return 'value a';
    }
}

class B implements MagicIntreface
{

    public function get($name)
    {
        if (!is_string($name)) {
            throw new InvalidArgumentException('Name must be a string');
        }
        return 'value b';
    }
}

Соответственно в реализации A не валидное исключение (должно быть InvalidArgumentException а не RuntimeException

Можно написать конечно тест для обоих реализаций.
class ATest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException InvalidArgumentException
     */
    public function testGetInvalidName()
    {
        $magic = new A;
        $magic->get(123);
    }
}

class BTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException InvalidArgumentException
     */
    public function testGetInvalidName()
    {
        $magic = new B;
        $magic->get(123);
    }
}

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

Как еще можно решить подобную проблему?
  • Вопрос задан
  • 299 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы