Reputation: 67695
I have the following test case:
include_once('../Logger.php');
class LoggerTest extends PHPUnit_Framework_TestCase {
public function providerLogger() {
return new Logger;
}
/**
* @dataProvider providerLogger
*/
public function testAddStream($logger) {
$this->assertTrue(false);
}
}
When I run it in PHPUnit, I get:
PHPUnit 3.4.14 by Sebastian Bergmann.
..........
Time: 0 seconds, Memory: 5.75Mb
OK (1 tests, 0 assertions)
Test should fail, but it doesn't. I tried having:
public function providerLogger() {
return array(new Logger);
}
But I get:
The data provider specified for LoggerTest::testAddStream is invalid.
I tried declaring it static
(like the manual says), but still no difference.
I remember having it working in a similar fashion before, but I could be wrong. What am I missing?
Thanks in advance for your help.
PHPUnit 3.4.14 (taken from PEAR) on PHP 5.3.3
Upvotes: 26
Views: 32877
Reputation: 131871
Minor update: It's OK to use instance methods as provider since version 3.2 (or somewhere around that). Have a look at the comments
The provider must look like this.
public static function providerLogger() {
return array(
array(new Logger)
);
}
First of all: The method must be static if you are using phpunit version lower than 3.3 .
The array s are important. Its not that hard to understand. The outer array has one value for each iteration the test should get called. Here the test just get called once. The inner arrays are the parameters (in order) the test is invoked with. Your test expects exactly one parameter, so the inner arrays always needs exactly one value. Another little example
public static function addTestProvider () {
return array(
/* First + Second = third? */
array(1,4,5),
array(3,3,6),
array(5,5,6)
);
}
public function testAdd ($a, $b, $result) {
$this->assertEquals($result, $a + $b);
}
Here testAdd gets executed 3 times, one for every second-level array, and it will receive the values from the inner array s. You may notice, that the test will fail and provides you a message in which iteration of the dataset (here #3, because 5+5 is not 6 ;)) the assertion failed.
Upvotes: 33
Reputation: 2783
Behold I have achieved a pattern to achieve test dependencies for dataProviders! In this way you can chain dataProviders.
class ProviderDependencyTest extends PHPUnit_Framework_TestCase
{
private static $dataSet;
public function provideData()
{
self::$dataSet = array(
array(2,2,4),
array(1,0,2),
array(0,0,0)
);
//use static storage so you don't have to call the dataProvider again
return self::$dataSet;
}
public function testProvideAdd()
{
$data = self::$dataSet;
$this->assertEquals(3,count($data[0]));
return $data[0];
}
/**
* @depends testProvideAdd
*/
public function testAdd($data)
{
$sum = $data[0] + $data[1];
$this->assertEquals($data[2], $sum);
return array($sum,$data[0],$data[1]);
}
/**
* @depends testAdd
*/
public function testSubtract($data)
{
$difference = $data[0] - $data[1];
$this->assertEquals($data[2], $difference);
return array($difference,$data[0],$data[1]);
}
/**
* @depends testSubtract
*/
public function testMultiply($data)
{
$product = $data[0] * $data[2];
$this->assertEquals($data[1], $product);
return $product;
}
/**
* @depends testMultiply
*
* @dataProvider provideData
*/
public function testMath($a,$b,$c)
{
//don't redo the first set of tests
if(array($a,$b,$c) == self::$dataSet[0])
{
return;
}
$sum = $this->testAdd(array($a,$b,$c));
$difference= $this->testSubtract($sum);
$product = $this->testMultiply($difference);
$this->assertInternalType('integer', $product);
}
}
The 2nd data set fails 1 test to illustrate.
Upvotes: -2
Reputation: 21
<?php
require_once 'calculator.php';
/**
* Calculator test case.
*/
class CalculatorTest extends PHPUnit_Framework_TestCase {
/**
* @var Calculator
*/
private $Calculator;
/**
* Prepares the environment before running a test.
*/
protected function setUp() {
parent::setUp ();
// TODO Auto-generated CalculatorTest::setUp()
$this->Calculator = new Calculator(/* parameters */);
}
/**
* Cleans up the environment after running a test.
*/
protected function tearDown() {
// TODO Auto-generated CalculatorTest::tearDown()
$this->Calculator = null;
parent::tearDown ();
}
/**
* Constructs the test case.
*/
public function __construct() {
// TODO Auto-generated constructor
}
/**
* Tests Calculator->add()
*
* @dataProvider provider
*/
public function testAdd($a, $b, $c) {
// TODO Auto-generated CalculatorTest->testAdd()
//$this->markTestIncomplete ( "add test not implemented" );
//$this->Calculator->add(/* parameters */);
$this->assertEquals($this->Calculator->add($a, $b), $c);
}
public static function provider()
{
return array(
array(1, 1, 1),
array(1, 1, -1),
array(4, 2, 2),
array(1, 1, 1)
);
}
}
is the complete set of code
Upvotes: 1
Reputation: 3495
I have also found that you cannot directly chain data providers:
class ProviderTest extends PHPUnit_Framework_TestCase {
public function provider() {
return array(array('test'));
}
/**
* @dataProvider provider
*/
public function providerTest1($test) {
$this->assertTrue($test);
return array(array($test));
}
/**
* @dataProvider providerTest1
*/
public function providerTest2($test) {
$this->assertEquals('test', $test);
}
}
Apparently, PHPUnit calls all the provider functions before running any tests, so you can't even use separate provider functions to feed test result data to other tests. The best you can do is to simulate:
class ProviderTest extends PHPUnit_Framework_TestCase {
private $provider_data = array();
public function provider() {
return array(array('test'));
}
/**
* @dataProvider provider
*/
public function testProvider1($test) {
$this->assertFalse(empty($test));
array_push($this->provider_data, array($test));
}
/**
* @depends testProvider1
*/
public function testProvider2($test = NULL) {
if(is_null($test)) {
// simulate a provider
foreach($this->provider_data as $row) {
call_user_func_array(array($this, __METHOD__), $row);
}
} else {
$this->assertEquals('test', $test);
}
}
}
Upvotes: 0
Reputation: 1156
I had the same problem, and it was solved, when i deleted the empty constructor,that was auto generated. Iam not sure why this solves the problem. I also had no test method named like the class. The provider method doesnt need to be static, so far my test run without static. But also run when i make the provider method static
Upvotes: 6
Reputation: 3887
Remove the parameter from public function testAddStream($logger) and try again. I don't believe PHPUnit will invoke a test which requires parameters it is unable to pass.
Upvotes: -2