如何对 class 的构造函数接受一些参数的方法进行单元测试?
How to unit test the methods of a class whose constructor take some arguments?
我有一个 class 形式类似这样的:
class A{
public function __constructor(classB b , classC c){
//
}
public function getSum(var1, var2){
return var1+var2;
}
}
我的测试用例 class 是这样的:
use A;
class ATest extends PHPUnit_Framework_TestCase{
public function testGetSum{
$a = new A();
$this->assertEquals(3, $a->getSum(1,2));
}
}
然而,当我 运行 phpunit 时,它会抛出一些错误,如:
Missing argument 1 for \..\::__construct(), called in /../A.php on line 5
即使我提供参数,它也会抛出相同的错误,但在不同的文件中。
说,我实例化
$a = new A(new classB(), new classC());
然后,对于 classB 的构造函数,我得到了相同的错误(classB 的构造函数与 A 的构造函数具有相似的形式)。
Missing argument 1 for \..\::__construct(), called in /../B.php on line 10
有没有其他方法,我可以测试功能或我缺少的东西。
我不想使用 mock (getMockBuilder(),setMethods(),getMock()) 进行测试,因为它似乎违背了单元测试的全部目的。
单元测试背后的基本思想是测试 class / 方法本身,而不是此 class 的依赖项。为了对 class A
进行单元测试,您不应使用构造函数参数的真实实例,而应使用 mocks。 PHPUnit
提供了很好的创建方式,所以:
use A;
class ATest extends PHPUnit_Framework_TestCase{
public function testGetSum{
$arg1Mock = $this->getMock('classB'); //use fully qualified class name
$arg2Mock = $this->getMockBuilder('classC')
->disableOriginalConstructor()
->getMock(); //use mock builder in case classC constructor requires additional arguments
$a = new A($arg1Mock, $arg2Mock);
$this->assertEquals(3, $a->getSum(1,2));
}
}
注意:如果您不会在此处使用模拟,而是使用真实的 classB 和 classC 实例,则它将不再是单元测试 - 它将是功能测试
您可以使用方法 setMethods
告诉 PHPUnit 您想要模拟指定 class 的哪个方法。 From the doc:
setMethods(array $methods)
can be called on the Mock Builder object
to specify the methods that are to be replaced with a configurable
test double. The behavior of the other methods is not changed. If you
call setMethods(null)
, then no methods will be replaced.
所以你可以构造你的 class 而无需替换任何方法,但绕过构造如下(工作)代码:
public function testGetSum(){
$a = $this->getMockBuilder(A::class)
->setMethods(null)
->disableOriginalConstructor()
->getMock();
$this->assertEquals(3, $a->getSum(1,2));
}
希望对您有所帮助
我有一个 class 形式类似这样的:
class A{
public function __constructor(classB b , classC c){
//
}
public function getSum(var1, var2){
return var1+var2;
}
}
我的测试用例 class 是这样的:
use A;
class ATest extends PHPUnit_Framework_TestCase{
public function testGetSum{
$a = new A();
$this->assertEquals(3, $a->getSum(1,2));
}
}
然而,当我 运行 phpunit 时,它会抛出一些错误,如:
Missing argument 1 for \..\::__construct(), called in /../A.php on line 5
即使我提供参数,它也会抛出相同的错误,但在不同的文件中。
说,我实例化
$a = new A(new classB(), new classC());
然后,对于 classB 的构造函数,我得到了相同的错误(classB 的构造函数与 A 的构造函数具有相似的形式)。
Missing argument 1 for \..\::__construct(), called in /../B.php on line 10
有没有其他方法,我可以测试功能或我缺少的东西。
我不想使用 mock (getMockBuilder(),setMethods(),getMock()) 进行测试,因为它似乎违背了单元测试的全部目的。
单元测试背后的基本思想是测试 class / 方法本身,而不是此 class 的依赖项。为了对 class A
进行单元测试,您不应使用构造函数参数的真实实例,而应使用 mocks。 PHPUnit
提供了很好的创建方式,所以:
use A;
class ATest extends PHPUnit_Framework_TestCase{
public function testGetSum{
$arg1Mock = $this->getMock('classB'); //use fully qualified class name
$arg2Mock = $this->getMockBuilder('classC')
->disableOriginalConstructor()
->getMock(); //use mock builder in case classC constructor requires additional arguments
$a = new A($arg1Mock, $arg2Mock);
$this->assertEquals(3, $a->getSum(1,2));
}
}
注意:如果您不会在此处使用模拟,而是使用真实的 classB 和 classC 实例,则它将不再是单元测试 - 它将是功能测试
您可以使用方法 setMethods
告诉 PHPUnit 您想要模拟指定 class 的哪个方法。 From the doc:
setMethods(array $methods)
can be called on the Mock Builder object to specify the methods that are to be replaced with a configurable test double. The behavior of the other methods is not changed. If you callsetMethods(null)
, then no methods will be replaced.
所以你可以构造你的 class 而无需替换任何方法,但绕过构造如下(工作)代码:
public function testGetSum(){
$a = $this->getMockBuilder(A::class)
->setMethods(null)
->disableOriginalConstructor()
->getMock();
$this->assertEquals(3, $a->getSum(1,2));
}
希望对您有所帮助