PHPUnit 如何测试一个方法是否有正确数量的参数?
PHPUnit how to test if a method has the correct amount of arguments?
在开始拍摄我之前,只是想知道我是单元测试方面的新手,所以我什至不知道我在这里发布的问题是否有可能实现。
所以,我喜欢做的是测试 class 的构造函数方法是否获得一定数量的参数。我该怎么做?
我的基本class如下:
class Time {
public function __construct() {
}
}
我的测试如下:
require dirname(dirname(__FILE__)) . "/time.php";
require dirname(dirname(__FILE__)) . "/vendor/autoload.php";
class TimeTests extends PHPUnit_Framework_TestCase {
protected $classInstance;
protected function setUp()
{
$this->classInstance = new Time();
}
public function testConstructorExists() {
$this->assertTrue ( method_exists( $this->classInstance , '__construct' ), 'Constructor method does not exists' );
}
}
目前第一个测试正常,但我不知道如何测试构造函数参数。
对于这个构造函数,我喜欢有三个整数参数,那么,我怎样才能正确测试参数是否存在?
我想到的一个可能的解决方案是在构造函数中使用 Throw Exception,但我还是不知道这是否正确。
有什么帮助吗? :)
您可以使用 PHP 反射来执行此操作:
$class = new ReflectionClass('ReflectionClass');
$constructor = $class->getConstructor();
$numberOfParams = $constructor->getNumberOfRequiredParameters();
您可以查看 PHP 文档:
http://php.net/manual/en/reflectionclass.getconstructor.php
http://php.net/manual/en/reflectionfunctionabstract.getnumberofrequiredparameters.php
您通过在测试中调用构造函数参数来测试它们是否正确。您不需要指定 __construct
方法存在或它需要三个参数(因为您的示例是一个 Time 对象,它甚至可能需要一个或两个)。
您想测试一下您将如何使用 class。你说接受三个参数,所以可能是小时、分钟和秒。现在,您可能会有一些方法来 return 显示时间的字符串。让我们测试一下:
public function testGetTime() {
$hour = 12;
$minute = 34;
$second = 13;
$time = new Time($hour, $minute, $second);
$this->assertEquals("$hour:$minute:$second", $time->getTime());
}
所以为了通过这个测试,你必须创建一个接受三个参数的构造函数并创建一个输出时间的方法。
稍后,我可能会决定让用户不指定秒数,这是一种常见的做法。然后我像这样添加测试:
public function testGetTimeNoSeconds() {
$hour = 3;
$minute = 34;
$time = new Time($hour, $minute);
$this->assertEquals("$hour:$minute:00", $time->getTime());
}
哦,看,最后一个构造函数参数现在是可选的!!你必须更新它,没问题。
有了这个,我们的构造函数得到了很多测试。但是有了这个,我不需要知道这个方法是什么样子的。我只需要知道 class 应该做什么。像您希望的那样限制方法会降低您的测试的可用性,并且会妨碍轻松重构。
使用方便的数据提供程序可以轻松测试无效参数:
/**
* @dataProvider dataInvalidParameters
*/
public function testInvalidParameters($hour, $minute, $second, $message) {
$this->setExpectedException('InvalidArgument', $message);
$time = new Time($hour, $minute, $second);
}
public function dateInvalidParameters() {
return [
['a', 12, 23, 'Hour must be an integer'],
[12, 'b', 23, 'Minute must be an integer'],
[12, 12, 'c', 'Second must be an integer'],
];
}
如果你想指定值在正确的范围内,很容易添加另一个测试用例。
在开始拍摄我之前,只是想知道我是单元测试方面的新手,所以我什至不知道我在这里发布的问题是否有可能实现。
所以,我喜欢做的是测试 class 的构造函数方法是否获得一定数量的参数。我该怎么做?
我的基本class如下:
class Time {
public function __construct() {
}
}
我的测试如下:
require dirname(dirname(__FILE__)) . "/time.php";
require dirname(dirname(__FILE__)) . "/vendor/autoload.php";
class TimeTests extends PHPUnit_Framework_TestCase {
protected $classInstance;
protected function setUp()
{
$this->classInstance = new Time();
}
public function testConstructorExists() {
$this->assertTrue ( method_exists( $this->classInstance , '__construct' ), 'Constructor method does not exists' );
}
}
目前第一个测试正常,但我不知道如何测试构造函数参数。
对于这个构造函数,我喜欢有三个整数参数,那么,我怎样才能正确测试参数是否存在?
我想到的一个可能的解决方案是在构造函数中使用 Throw Exception,但我还是不知道这是否正确。
有什么帮助吗? :)
您可以使用 PHP 反射来执行此操作:
$class = new ReflectionClass('ReflectionClass');
$constructor = $class->getConstructor();
$numberOfParams = $constructor->getNumberOfRequiredParameters();
您可以查看 PHP 文档: http://php.net/manual/en/reflectionclass.getconstructor.php http://php.net/manual/en/reflectionfunctionabstract.getnumberofrequiredparameters.php
您通过在测试中调用构造函数参数来测试它们是否正确。您不需要指定 __construct
方法存在或它需要三个参数(因为您的示例是一个 Time 对象,它甚至可能需要一个或两个)。
您想测试一下您将如何使用 class。你说接受三个参数,所以可能是小时、分钟和秒。现在,您可能会有一些方法来 return 显示时间的字符串。让我们测试一下:
public function testGetTime() {
$hour = 12;
$minute = 34;
$second = 13;
$time = new Time($hour, $minute, $second);
$this->assertEquals("$hour:$minute:$second", $time->getTime());
}
所以为了通过这个测试,你必须创建一个接受三个参数的构造函数并创建一个输出时间的方法。
稍后,我可能会决定让用户不指定秒数,这是一种常见的做法。然后我像这样添加测试:
public function testGetTimeNoSeconds() {
$hour = 3;
$minute = 34;
$time = new Time($hour, $minute);
$this->assertEquals("$hour:$minute:00", $time->getTime());
}
哦,看,最后一个构造函数参数现在是可选的!!你必须更新它,没问题。
有了这个,我们的构造函数得到了很多测试。但是有了这个,我不需要知道这个方法是什么样子的。我只需要知道 class 应该做什么。像您希望的那样限制方法会降低您的测试的可用性,并且会妨碍轻松重构。
使用方便的数据提供程序可以轻松测试无效参数:
/**
* @dataProvider dataInvalidParameters
*/
public function testInvalidParameters($hour, $minute, $second, $message) {
$this->setExpectedException('InvalidArgument', $message);
$time = new Time($hour, $minute, $second);
}
public function dateInvalidParameters() {
return [
['a', 12, 23, 'Hour must be an integer'],
[12, 'b', 23, 'Minute must be an integer'],
[12, 12, 'c', 'Second must be an integer'],
];
}
如果你想指定值在正确的范围内,很容易添加另一个测试用例。