如何对构造函数采用某些参数的类的方法进行单元测试?

时间:2016-09-08 11:45:36

标签: php unit-testing symfony constructor phpunit

我有一类这样的形式:

class A{  
    public function __constructor(classB b , classC c){
    //
    }

    public function getSum(var1, var2){
        return var1+var2;
    }
}

我的测试用例类是这样的:

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())进行测试,因为它似乎无视单元测试的整个目的。

2 个答案:

答案 0 :(得分:4)

单元测试背后的基本思想是测试一个类/方法本身,而不是这个类的依赖。为了对您的类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)); } } 提供了创建方法的好方法,所以:

function Project.on_level_load_pre_flow()
    setObjPostion(Project.level_names.testLv,"mainobj",stingray.Vector3( 100, 100, 100 ))
end


function setObjPostion(levelsString,newObjString,newPosition)
    world = stingray.Application.new_world()
    world:load_level(levelsString)
    myobj = stingray.World.unit_by_name(world,newObjString)
    --local newPosition2= stingray.Vector3( 100, 100, 1 )
    stingray.Unit.set_local_position(myobj,1,newPosition)
end

注意:如果你不是在这里使用模拟,而是真正的classB和classC实例,它将不再是单元测试 - 它将是一个功能测试

答案 1 :(得分:1)

您可以使用方法setMethods告诉PHPUnit您想要模拟指定类的方法。 From the doc

  可以在Mock Builder对象上调用

setMethods(array $methods)   指定要用可配置替换的方法   测试双倍。其他方法的行为不会改变。如果你   调用setMethods(null),然后不会替换任何方法。

因此,您可以在不替换任何方法的情况下构建您的类,但绕过构造如下(工作)代码:

public function testGetSum(){
    $a = $this->getMockBuilder(A::class)
        ->setMethods(null)
        ->disableOriginalConstructor()
        ->getMock();

    $this->assertEquals(3, $a->getSum(1,2));
}

希望这个帮助