I have a class of form something like this:
class A{
public function __constructor(classB b , classC c){
//
}
public function getSum(var1, var2){
return var1+var2;
}
}
My test case class is something like this:
use A;
class ATest extends PHPUnit_Framework_TestCase{
public function testGetSum{
$a = new A();
$this->assertEquals(3, $a->getSum(1,2));
}
}
However when I run the phpunit, it throws some error like:
Missing argument 1 for \..\::__construct(), called in /../A.php on line 5
Even if I provide the arguments, it throws the same error but in different file.
say, I instantiate by
$a = new A(new classB(), new classC());
Then, I get the same error for the constructor of classB(the constructor of classB has similar form to that of A).
Missing argument 1 for \..\::__construct(), called in /../B.php on line 10
Is there any other way, I can test the function or something which I am missing.
I don't want to test by using mock (getMockBuilder(),setMethods(),getMock()) as it seems to defy the whole purpose of unit testing.
To test that a constructor does its job (of making the class invariant true), you have to first use the constructor in creating a new object and then test that every field of the object has the correct value. Yes, you need need an assertEquals call for each field.
because your operation should fail if that object is null which makes sense the "behavior" fails and we should unit test that rather the actual constructors.
JUnit provides lot of methods to test our cases. We can test the constructor of a class using the same techniques we have used in our previous examples. Sometimes we need to initialize the objects and we do them in a constructor. In JUnit we can also do same using the @Before method.
The constructor has no logic besides setting up the fields. So the only thing you can test is that the same values passed into the constructor are accessible via getter methods.
The basic idea behind unit test it to test a class / method itself, not dependencies of this class. In order to unit test you class A
you should not use real instances of your constructor arguments but use mocks instead. PHPUnit
provides nice way to create ones, so:
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));
}
}
Note: If you won't be using mock's here but a real classB and classC instances it won't be unit test anymore - it will be a functional test
You could tell to PHPUnit which method you want to mock of a specified class, with the methods setMethods
. 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.
So you can construct your class without replacing any methods but bypass the construct as following (working) code:
public function testGetSum(){
$a = $this->getMockBuilder(A::class)
->setMethods(null)
->disableOriginalConstructor()
->getMock();
$this->assertEquals(3, $a->getSum(1,2));
}
Hope this help
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With