如何对 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 进行单元测试,您不应使用构造函数参数的真实实例,而应使用 mocksPHPUnit 提供了很好的创建方式,所以:

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));
}

希望对您有所帮助