如果两个或多个测试相同接口/抽象类的不同实现的测试类具有共同的测试但具有不同的夹具,那么重构测试用例是一个好主意吗?
假设代码和测试如下所示:
interface MathOperation
{
public function doMath($a, $b);
}
class Sumator implements MathOperation
{
public function doMath($a, $b)
{
return $a + $b;
}
}
class Multiplicator implements MathOperation
{
public function doMath($a, $b)
{
return $a * $b;
}
}
// tests
class SumatorTest extends PHPUnit_Framework_TestCase
{
/**
* @var Sumator
*/
protected $sumator;
public function setUp()
{
$this->sumator = new Sumator;
}
/**
* @dataProvider fixtures
*/
public function testDoMath($a, $b, $expected)
{
$result = $this->sumator->doMath($a, $b);
$this->assertEqual($expected, $result);
}
public function fixtures()
{
return array(
array(1, 1, 2);
array(2, 1, 3);
array(100, -1, 99);
);
}
}
class MultiplicatorTest extends PHPUnit_Framework_TestCase
{
/**
* @var Multiplicator
*/
protected $multiplicator;
public function setUp()
{
$this->multiplicator = new Multiplicator;
}
/**
* @dataProvider fixtures
*/
public function testDoMath($a, $b, $expected)
{
$result = $this->multiplicator->doMath($a, $b);
$this->assertEqual($expected, $result);
}
public function fixtures()
{
return array(
array(1, 1, 1);
array(2, 1, 2);
array(100, -1, -100);
);
}
}
我希望它们(测试)看起来像这样:
class MathOperationTestCase extends PHPUnit_Framework_TestCase
{
/**
* @var MathOperation
*/
protected $operation;
public function setUp()
{
$this->operation = $this->createImpl();
}
/**
* @return MathOperation
*/
abstract function createImpl();
/**
* @dataProvider fixtures
*/
public function testDoMath($a, $b, $expected)
{
$result = $this->operation->doMath($a, $b);
$this->assertEqual($expected, $result);
}
abstract public function fixtures();
}
class SumatorTest extends MathOperationTestCase
{
public function createImpl()
{
return new Sumator;
}
public function fixtures()
{
return array(
array(1, 1, 2);
array(2, 1, 3);
array(100, -1, 99);
);
}
}
class MultiplicatorTest extends MathOperationTestCase
{
public function createImpl()
{
return new Multiplicator;
}
public function fixtures()
{
return array(
array(1, 1, 1);
array(2, 1, 2);
array(100, -1, -100);
);
}
}
这似乎结构更好,但可能缺乏可读性。所以最后我不确定它是否有用。