I have an abstract class defined in my project that I want to run tests on.
<?php
use PHPUnit\Framework\TestCase;
use phpDM\Connections\Adapters\ConnectionAdapterInterface;
include(__DIR__ . '/../../../src/Connections/Adapters/ConnectionAdapterInterface.php');
class TestConnection { }
class ConnectionAdapterInterfaceTest extends TestCase
{
function testCreateConnection() {
$interface = $this->getMockForAbstractClass('ConnectionAdapterInterface');
$interface->method('createConnection')
->willReturn(new TestConnection());
$connection = $interface::createConnection();
$this->assertInstanceOf(TestConnection, $connection);
}
}
The ConnectionAdapterInterface is a (poorly named) abstract class:
abstract class ConnectionAdapterInterface {
abstract public static function createConnection(array $config);
}
However, no matter what I do, I keep getting the error Class "ConnectionAdapterInterface" does not exist.. In the sample above, I have both a use and include, though I also tested with each one at a time.
Related
I have an abstract database class named as:
abstract class database {
protected $value;
}
I created another abstract class
abstract class my_database extends database {
public function set_value($value) {
$this->value = $value;
}
}
When I try to use it:
$my_db = new my_database();
I get error:
Fatal error: Cannot instantiate abstract class my_database in ...
What I try to do is: The abstract class database has a protected $value and I would like to create a wrapper class, to be able to change the protected value (temporarily).
How can I do that?
EDIT1: unfortunately earlier, when I tried without abstract my_database, I got the errors:
- abstract methods and must therefore be declared abstract or implemented
- Abstract function cannot contain body
EDIT2:
After taking out the abstract word completely from my_database, I got the following error:
Fatal error: Class my_database contains 32 abstract methods and must
therefore be declared abstract or implement the remaining methods
How can I fix this?
Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. You can read about this in PHP's documentation here: link
Here's an example.
There is an abstract class (note that abstract methods don't have body - they CAN'T have body - it's just a signature):
abstract class AbstractClass
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// Common method. It will be available for all children - they don't have to declare it again.
public function printOut() {
print $this->getValue() . "\n";
}
}
Extend your abstract class with a class like this (note that all abstract methods MUST be defined in concrete class):
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
Then you can create instance of ConcreteClass1:
$class1 = new ConcreteClass1;
Your class should not be abstract:
class my_database extends database {
public function set_value($value) {
$this->value = $value;
}
}
In OOP, abstract class can't be instanciated juste it can be extended.
i have become a bit confused about abstract class ! i have read more of the post written in stackoverflow and another website but i didn't understand ! so i took a look at my book again but i didn't understand it either . so please analyze the code below step by step :
thanks in advance
<?php
abstract class AbstractClass
{
abstract protected function getValue();
public function printOut() {
print $this->getValue();
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
$class2 = new ConcreteClass2;
$class2->printOut();
?>
By definition
'An abstract class is a class that is declared abstract —it may or may
not include abstract methods. Abstract classes cannot be instantiated,
but they can be subclassed. An abstract method is a method that is
declared without an implementation'.
If defined an abstract class, you should extend that class with another.
In case of having abstract methods within the abstract class, you should write them in the child class in order to instantiate the child.
Related to the code, that is why when you instantiate the ConcreteClass, the getValue function is 'overwritten' to the pattern, while calling to the printOut method is from the father itself, because It is already written and not overwritten by the child. (See also that method was not abstract, that is why you can also use it from the father class)
Your code is right. Abstact class mean, when you can not make a instance of it. You can not do this:
$abstract = new AbstractClass();
For some reason when I try to test abstract class I get PHPUnit_Framework_MockObject_RuntimeException: Class "AbstractClass" does not exist.
Here's the code
AbstractClass.php
<?php
namespace SD\Project;
abstract class AbstractClass
{
public function handle()
{
}
}
AbstractClassTest.php
<?php
require_once 'AbstractClass.php';
use SD\Project\AbstractClass;
class AbstractClassTest extends PHPUnit_Framework_TestCase
{
public function testHandle()
{
$stub = $this->getMockForAbstractClass('AbstractClass');
}
}
When I get rid off the namespace and use statements the code is executed successfully. What I'm doing wrong?
You are not using the fully qualified path of the class.
$stub = $this->getMockForAbstractClass('\SD\Project\AbstractClass');
Read Similar: PHPUnit, Interfaces and Namespaces (Symfony2)
Examples: http://theaveragedev.com/testing-abstract-classes-with-phpunit/
I am using PHPUnit to unit test my application (using Zend Framework 2). I am stuck in a situation where I need to call a method that is in one test class
from another test class. Let me explain myself with a small example:
<?php
// TestUser.php
namespace Test\User;
class UserTest extends \PHPUnit_Framework_TestCase
{
public static function GetUserCount(){
// some code here
}
}
?>
<?php
// TestAdmin.php
namespace Test\Admin;
use Test\User;
class AdminTest extends \PHPUnit_Framework_TestCase
{
public static function AdminAction(){
Test\User::GetUserCount();
}
}
?>
When I call the Test\User::GetUserCount(); or User::GetUserCount(); I get the following error:
PHP Fatal error: Class 'Test\User' not found in path/to/TestAdmin.php
on line 11
Any idea if the method is callable from one test class to another test class? If yes, how?
Thanks
Normally, you would Mock the other class call, to ensure the returned values are what your class is expecting. You may also link some test together with Test Dependencies.
I have added a short sample. Note, I assume you added the AdminAction and GetUserCount() as samples since these are not really test methods that you would have with PHPUnit tests.
TestUser.php
<?php
namespace Test\User;
class UserTest extends \PHPUnit_Framework_TestCase
{
protected $UserObject;
public function setUp()
{
$this->UserObject = new Test\User(); // Normal Object
}
public static function testGetUserCount()
{
$this->assertEquals(1, $this->UserObject->GetUserCount(), 'Testing the basic object will return 1 if initialized'); // Do your tests here.
}
}
TestAdmin.php
<?php
namespace Test\Admin;
class AdminTest extends \PHPUnit_Framework_TestCase
{
protected $AdminObject;
public function setUp()
{
$this->AdminObject = new Test\Admin();
}
public static function testAdminAction()
{
// Create a stub for the User class.
$stub = $this->getMock('User');
// Configure the stub.
$stub->expects($this->any())
->method('GetUserCount')
->will($this->returnValue(2));
// Calling $stub->GetUserCount() will now return 2. You can then ensure the Admin class works correctly, by changing what the mocks return.
$this->assertEquals(2, $stub->GetUserCount());
}
}
I have the following legacy file (can't edit):
class Test {
public $abc=1;
}
I need to extend this class from a name-spaced file:
use mynamespace;
class MyClass extends Test {
}
However my auto-load function attempts to include mynamespace\Test. How to specify that un-namespaced version of Test should be used?
Prefix the class name with a \:
class MyClass extends \Test {
...
}
From the manual on namespaces: "Note that to access any global class, function or constant, a fully qualified name can be used, such as \strlen() or \Exception or \INI_ALL."
Try this:
class MyClass extends \Test {
}