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/
Related
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.
I have the following class
namespace MyApp;
use MyApp\SomeInterface;
class MyClass
{
public function __construct(SomeInterface $s)
{
//Some Logic here
}
//Another methods implemented There
}
The SomeInterface contains the following:
namespace MyApp
interface SomeInterface
{
/**
* #return SomeObject
*/
public function someMethodToImpement();
}
And I want to create a mock over my phpunit Test Class:
namespace Tests\MyApp;
use PHPUnit\Framework\TestCase;
use MyApp\MyClass;
use MyApp\SomeInterface;
class MyClassTest extends TestCase
{
public function someTest()
{
$fakeClass=new class{
public function myFunction($arg1,$arg2)
{
//Dummy logic to test if called
return $arg1+$arg2;
}
};
$mockInterface=$this->createMock(SomeInterface::class)
->method('someMethodToImpement')
->will($this->returnValue($fakeClass));
$myActualObject=new MyClass($mockInterface);
}
}
But Once I run it I get the error:
Tests\MyApp\MyClassTest::someTest
TypeError: Argument 1 passed to MyApp\MyClass::__construct() must implement interface MyApp\SomeInterface, instance of PHPUnit\Framework\MockObject\Builder\InvocationMocker given, called in /home/vagrant/code/tests/MyApp/MyClassTest.php on line
Do you know why that happens and how actually will create the mock Interface?
Instead of constructing the mock via
$mockInterface=$this->createMock(SomeInterface::class)
->method('someMethodToImpement')->will($this->returnValue($fakeClass));
Split it into seperate lines:
$mockInterface=$this->createMock(SomeInterface::class);
$mockInterface->method('someMethodToImpement')->will($this->returnValue($fakeClass));
And will work like a charm.
I've had a similar issue. I fixed it by adding those interfaces as another mock() parameter
class Product implements PriceInterface, ProductDataInterface {
// ...
}
Test:
// throws error
$product = Mockery::mock(Product::class);
// works fine
$product = Mockery::mock(Product::class, 'PriceInterface, ProductDataInterface');
Link to documentation
so i have a class here that have a function who requires another class to create an object.
I use namespace in both files, my question is can i get rid of this line here: include("class.php"); and instantiate class using namespace?
here is the file from where i call the other class:
namespace namespaceName;
class classLoader{
public function __construct() {
//not used
}
public function executeFunctionOutsideTheNamespace() {
include("class.php");
new classExtended("badass");
}
}
and the class by itself:
namespace namespaceName;
class classExtended extends classBase
{
public function __construct($action) {
echo $action;
}
}
I ask again, using Namespace there is no possibility to get rid of include() or require(), require_once() functions? to call directly new classExtended("badass"); ?
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 {
}