PHPUnit如何测试一个方法是否具有正确数量的参数


PHPUnit how to test if a method has the correct amount of arguments?

在开始拍摄我之前,我只是想知道我对单元测试完全陌生,所以我甚至不知道我在这里发布的问题是否有可能实现。

所以,我喜欢做的是测试类的构造函数方法是否获得了一定数量的参数。我该怎么做?

我的基本课程如下:

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'],
    ];
}

如果您想指定值在正确的范围内,那么添加另一个测试用例是很容易的。