我正在构建一个简单的(单元)测试框架,用户可以在其中测试某个功能。
但现在我需要SetUp()
和TearDown()
功能。我只是不确定如何实现这一点。
我的代码看起来像这样:
class TestCase
{
public function SetUp ( ) { }
public function TearDown ( ) { }
// Down here are alot of assertion methods
public function AssertTrue ( )
{
return $this;
}
public function AssertFalse( )
{
return $this;
}
}
然后另一个类扩展了这个类:
class SomeTestCase extends TestCase
{
public function SetUp ( )
{
echo 'SetUp';
}
public function TearDown ( )
{
echo 'SetUp';
}
public function TestMethod1 ( )
{
// do some test
}
public function TestMethod2 ( )
{
// do some other test
}
}
现在SetUp()
方法需要在每个测试方法的开头运行。因此,在这种情况下TestMethod1
和TestMethod2
。
TearDown()
方法需要在每个测试方法结束时运行。
但我怎么能从TestCase
班级做到这一点。我不希望用户需要在每种方法中手动添加$this->SetUp()
和$this->TearDown()
。
我希望它的行为类似于__construct
,__destruct
,但是对于每种方法都是如此。
我该怎么做?
答案 0 :(得分:0)
为了做到这一点,你需要将setup()
硬编码到你的所有方法中,这些方法是愚蠢的,或者只有一个入口点不是测试方法之一。因此,我们立即想到的是一个触发器方法,它接受您或您的用户要执行的类的名称作为参数。例如:
public function trigger($method){
$this->SetUp();
$this->$method;
}
您从魔术函数__call
public function __call($method){
$this->trigger($method);
}
正如您可能已经想到的那样,您不能拥有与其“呼叫”名称同名的类,因为__call
永远不会执行。您需要在要调用的方法名称和无人知道的虚拟名称之间建立关系。
private $methodRelations = array(
'testMethod1' => 'dummyMethod1',
'testMethod2' => 'dummyMethod2'
)
然后整个班级看起来像
class TestCase{
private $methodRelations = array(
'testMethod1' => 'dummyMethod1',
'testMethod2' => 'dummyMethod2'
)
public function __call($method){
$this->trigger($this->methodRelations[$method]);
}
public function trigger($method){
$this->SetUp();
$this->$method;
}
public function dummyMethod1( )
{
// do some test
}
public function dummyMethod2( )
{
// do some test
}
}
对于更整洁的外观,您可以将trigger
与__call
结合使用,但为了更好地理解,我将它们分开了。祝好运!