constructor breaks phpunit tests with providers - php

Here's a test PHPUnit test I wrote:
<?php
class MyTest extends PHPUnit_Framework_TestCase
{
public function __construct()
{
echo "starting tests\r\n";
parent::__construct();
}
public function provider()
{
return array(array('test'));
}
/**
* #dataProvider provider
*/
public function testProvider($var)
{
$this->assertEquals($var, $var);
//exit($var);
}
}
When I run it I get the following:
There was 1 error:
1) MyTest::testProvider
Missing argument 1 for MyTest::testProvider()
/home/myname/test.php:19
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.
My question is... why? And what can I do about it?
In the actual unit tests I'm writing (the above is just a test demonstrating the problem) I'm testing a class with several different backend engines. I have an abstract class with a bunch of test cases and a protected class variable named $engine. I then have a bunch of classes that extend this abstract class and set $engine in the constructor. In each of the test methods in the abstract method $obj->setEngine($this->engine) is then called to test the specific engine in question. But this approach seems to break unit tests with providers and in lieu of that I'm not sure what I should be doing.
Any ideas?

Instead of implementing a constructor, you should use the static method setUpBeforeClass to create the $engine. The engine must be stored in a static property.
https://phpunit.de/manual/current/en/fixtures.html#fixtures.sharing-fixture

Related

PHPUnit - implementing abstract method in child

I have a set of read-only tests and a couple of ones that modify data (insert/update/delete). I'd like to back up my tables, so each test class would have a list of associated tables that they'll modify. This is just test data.
I thus thought of this:
abstract class DataAlteringTestBase extends PHPUnit_Framework_TestCase
{
protected function setUp()
{
echo "backing up tables: " . $this->GetAlteredTableNames();
}
public abstract function GetAlteredTaleNames();
}
One of the subclasses:
class DataAlteringTest extends DataAlteringTestBase
{
function GetAlteredTaleNames()
{
return array("some_table");
}
public function testDummyStuffChild()
{
$this->assertTrue(true);
}
}
The problem is, I think, that PHPUnit tries to get the method implementation from the abstract class, rather than its children.
Call to undefined method DataAlteringTest::GetAlteredTableNames() -
the implementation ...\tests\DataAlteringTestBase.php:6 - the abstract
class
How to fix it? or is there something wrong with the idea of implementing this in PHP/PHPUnit in the first place?
You have a few typos - you wrote GetAlteredTaleNames() in some places and GetAlteredTableNames() in other places.

Why does my PHPUnit Fixtures Stack test is not working properly?

I've been reading this manual, but I'm not understanding why the $stack loose the values after each test function.
Here's my code:
require_once BASE . 'Transaction.php';
class TransactionTest extends PHPUnit_Framework_TestCase
{
protected $stack;
protected function setUp()
{
Database::getInstance()->connect();
$this->stack = new Transaction(123456789);
}
public function testInsert()
{
$data['name'] = 'Omega';
$this->stack->set($data);
$this->assertTrue($this->stack->save());
}
public function testUpdate()
{
$object = PHPUnitReflectionClass::getInstance($this->stack);
$this->assertEquals(array('name' , 'Omega'), $object->getProperty('name'));
}
}
At the "testUpdate" function, I don't have the name.
If I just copy all the PHPUnit example, all tests will run perfectly, but I'm not able to see the values using var_dump at the next function. And this is another thing that I don't get it.
The problems are:
the setup method is called before each test method invocation;
your test are depends each other.
For the first problem you can use the setUpBeforeClass method. From the doc:
The setUp() and tearDown() template methods are run once for each test
method (and on fresh instances) of the test case class.
In addition, the setUpBeforeClass() and tearDownAfterClass() template
methods are called before the first test of the test case class is run
and after the last test of the test case class is run, respectively.
For the second problem, is a bad practice to have tests that depends each otherbut PHPUnit supports the declaration of explicit dependencies between test methods, so you can use the #depends annotation to express dependencies: if a test fail the other is not executed.
So your test class can be, as example:
require_once BASE . 'Transaction.php';
class TransactionTest extends PHPUnit_Framework_TestCase
{
protected static $stack;
public static function setUpBeforeClass()
{
Database::getInstance()->connect();
$this->stack = new Transaction(123456789);
}
public function testInsert()
{
$data['name'] = 'Omega';
$this->stack->set($data);
$this->assertTrue($this->stack->save());
}
/**
* #depends testInsert
*/
public function testUpdate()
{
$object = PHPUnitReflectionClass::getInstance($this->stack);
$this->assertEquals(array('name' , 'Omega'), $object->getProperty('name'));
}
}
Hope this help
Unit tests should not depend on other tests, it's considered bad practice. The point of unit tests is that they run in a controlled and isolated environment. The setUp() and tearDown() methods are called respectively before and after each test method. And thus your $stack property is overwritten before each test. This is also pointed out in the document you linked to (just below example 4.1):
The setUp() and tearDown() template methods are run once for each test method (and on fresh instances) of the test case class.
(You're also making the assumption that the methods in your test class are run in the same order that they are written, but that isn't necessarily the case. Most of the time they do run in the same order, but you can't depend on it.)

Is it compulsory to declare abstract class for abstract method?

I have a below program
<?php
abstract class foo
{
abstract public function callme();
public function testing()
{
return $this->callme();
}
}
class bar extends foo
{
public function callme()
{
return "hello";
}
}
$objBar = new bar();
echo $objBar->testing();
?>
I defined abstract class foo. Is it compulsory to write abstract before class ? Because if i removed abstract i am getting fatal error.
Yes, if it contains abstract methods.
By declaring a method as abstract you are saying that in order to use this class, extending classes must implement the abstract method.
Your foo class cannot be instantiated unless callme is implemented, hence it must be declared abstract.
These concepts are perhaps better explained with a real world example than your standard abstract class Vehicle, class Car extends Vehicle tutorials.
Let's say we have a reporting system that does some querying on the database.
We find that all reports must be implemented in a standard way to share code and help with future maintenance.
So we define:
abstract class Report
{
}
For the sake of argument, all of our reports require a database connection.
abstract class Report
{
/** #var PDO */
protected $dbh;
public function __construct (PDO $dbh)
{
$this->dbh = $dbh;
}
/**
* #return array
*/
abstract public function getData();
}
Here we have also decided that all of our reports must implement a public getData method that returns an array.
This means:
We can ensure all our reports have a database connection
We can instantiate and then run each report in the same way
The abstract class definition has enforced the way we consume this code and makes sure that every type of report, regardless of which developer on your team wrote it, conforms to the convention we have decided.
Other code is then able to select a report from user input, run it, and do something with the result of getData (such as writing it to a CSV file) knowing that it will be an array.

PHPUnit setUp() never called

When I run phpunit, my fixtures are null. I initialize the fixtures in setUp(), but my debugging has shown it is never called. I tried having the member variables be assigned the proper values in the child class, but they remain null, which boggles my mind.
// Unit/Base.Unit.php
Class BaseUnit extends PHPUnit_Framework_TestCase {
// Tests for Base Object methods
}
// Unit/Validation/Validation.Unit.php
Class ValidationUnit extends BaseUnit {
protected $validationClass;
protected $validData;
protected $invalidData;
protected function newValidationInstance($data) {
return new $this->validationClass($data);
}
public function testValidData() {
$instance = $this->newValidationInstance($this->validData);
$this->assertEquals('true', $instance->isValid());
}
// ... other tests for validation ...
}
// Unit/Validation/Email.Test.php
Class EmailTest extends ValidationUnit {
protected function setUp() {
$this->class = "Email";
$this->validData = "test#gmail.com";
$this->invalidData = "fdksljfa";
}
}
Running PHPUnit...
phpunit --bootstrap /some/config.php Unit/
PHPUnit 4.2.2 by Sebastian Bergmann.
.E
Fatal error: Class name must be a valid object or a string in /opt/bitnami/some/path/Unit/Validation/Validation.Unit.php on line 9
What I'm expecting to happen is for phpunit to start tests on EmailTest, and run the tests both in it and it's parent classes. The Validation class has a ton of subclasses (Email, ZipCode, etc) so having all the testing in Validation is a huge win.
But I can't call setUp(), so I can't instantiate the proper Validation classes.
Edit
So it turns out that setUp() is called before any tests in the class that setUp() is defined in but not before other tests, including tests in parent classes.
So in order to control the order of tests, I'm having each class define an invokeTests() function containing it's tests, and then calling it's parent's invokeTests() method. That way, tests will be executed with respect to OO hierarchy.

PHPUnit: Testdependencies with test from parentclass

So, I've got a little problem with my Unittests. I wrote some basisclasses for different Testcases and I want to uses some prepared test-methods.
i.e.
class ModelTestCase extends PHPUnit_Framework_TestCase {
public function testCreateInstance() { ... }
}
class UserModelTest extends ModelTestCase {
/**
* (at)depends testCreateInstance
*/
public funcion testWhatever($model) { ...}
}
Is there any trick to use it as I want or must I really write every test in every class?
It all depends on what you really want to do, your code sample is way too vague to tell that.
One option for you is to create your own setup() method in ModelTestCase (dont forget to call parent::setUp()) and do some initialization in there.
If you want to test only the derived model tests, but not the base class itself, you can declare it as abstract:
abstract class ModelTestCase extends PHPUnit_Framework_TestCase {
public function testCreateInstance() { ... }
}
This worked for me.

Categories