在开始拍摄我之前,我只是想知道我对单元测试完全陌生,所以我甚至不知道我在这里发布的问题是否有可能实现。
所以,我喜欢做的是测试类的构造函数方法是否获得了一定数量的参数。我该怎么做?
我的基本课程如下:
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.phphttp://php.net/manual/en/reflectionfunctionabstract.getnumberofrequiredparameters.php
通过在测试中调用构造函数参数来测试构造函数参数是否正确。您不需要指定__construct
方法存在,也不需要指定它需要三个参数(由于您的示例是Time对象,它甚至可能需要一个或两个参数)。
你想测试你将如何使用你的课。你说要进行三次辩论,所以可能是一小时、一分钟和一秒钟。现在,您可能需要一些方法来返回一个显示时间的字符串。让我们测试一下:
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());
}
哦,看,最后一个构造函数参数现在是可选的!!你必须更新它,没问题。
有了这一点,我们的构造函数会受到很多测试。但有了这个,我不需要知道这个方法是什么样子的。我只需要知道这个类应该做什么。像你想做的那样约束方法会降低测试的可用性,并阻止容易的重构。
使用方便的数据提供程序可以很容易地测试无效参数,如
/**
* @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'],
];
}
如果您想指定值在正确的范围内,那么添加另一个测试用例是很容易的。