Добрый день возникла следующая ситуация.
Допустим есть произвольные интерфейсы 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);
}
}
но каждый раз копипастить подобные проверки не очень удобно особенно если одинаковых поведений много.
Как еще можно решить подобную проблему?