PHP - Fatal error: Class 'PHPUnit_Framework_Test - php

So I have started to use PHPUnit to test my programs.
I have this problem where I get an error when I try to test a program where the program is gonna control if a webpage exists.
The code:
<?php
class RemoteConnect
{
public function connectToServer($serverName=null)
{
if($serverName==null){
throw new Exception("That's not a server name!");
}
$fp = fsockopen($serverName,80);
return ($fp) ? true : false;
}
public function returnSampleObject()
{
return $this;
}
}
?>
And the test code to it:
<?php
require_once('RemoteConnect.php');
class RemoteConnectTest extends PHPUnit_Framework_TestCase
{
public function setUp(){ }
public function tearDown(){ }
public function testConnectionIsValid()
{
// test to ensure that the object from an fsockopen is valid
$connObj = new RemoteConnect();
$serverName = 'www.google.com';
$this->assertTrue($connObj->connectToServer($serverName) !== false);
}
}
?>
They are in the same directory named: PHPUnit inside the www (C:\wamp\www\PHPUnit)
But I don't understand why i get the error (Fatal error: Class 'PHPUnit_Framework_TestCase' not found in C:\wamp\www\PHPUnit\RemoteConnectTest.php on line 5)
My PHPUnit package path is (C:\wamp\bin\php\php5.3.10\pear\PHPUnit)
I have tried making a program MailSender, where it sends a mail with a text content in it, that was just for using PEAR. And it succeded, but I don't understand why this doesn't work.
Regards
Alex

Don't you need to have the PHPUnit_Framework_TestCase class available in RemoteConnectTest.php?
Add the following on top of the file:
require_once 'PHPUnit/Autoload.php';

Related

Why is my interface not found?

I'm learning PHP OOP and right now I built a basic calculator.
Here is my code at index.php:
require_once 'Calculator.class.php';
require_once 'Adder.class.php';
require_once 'Substract.class.php';
require_once 'Operator.interface.php';
require_once 'Multiplier.class.php';
require_once 'Devider.class.php';
$c = new Calculator;
$c->setOperation(new Adder);
$c->calculate(10,50); // 60
echo $c->getResult();
And this is the Calculator class file:
class Calculator
{
protected $result;
protected $operation;
public function setOperation(OperatorInterface $operation)
{
$this->operation = $operation;
// var_dump($operation);
}
public function calculate()
{
foreach(func_get_args() as $number)
{
$this->result = $this->operation->run($number,$this->result);
}
}
public function getResult()
{
return $this->result;
}
}
And this is the interface that is being called within this class file:
interface OperatorInterface
{
public function run($number,$result);
}
And this is the class Adder which is called from the index.php:
class Adder implements OperatorInterface
{
public function run($number,$result)
{
return $result + $number;
}
}
As you can see it looks nice and okay... however I get this weird error:
Fatal error: Interface 'OperatorInterface' not found on line 2 Adder.php
So line 2 of Adder Class is this:
class Adder implements OperatorInterface
Which means I have not include the interface properly. But I did include that.
So why am I getting this error?
Where did I make my mistake?
You need to include the Operator.interface.php file before the Adder.class.php file, otherwise when the compiler gets to the Adder class, it hasn't yet encountered anything called OperatorInterface, so it doesn't recognise it and can't verify that it's valid to declare that the Adder class implements it. Since it's also referenced in the Calculator class, you should include it before that as well.
require_once 'Operator.interface.php';
require_once 'Calculator.class.php';
require_once 'Adder.class.php';
require_once 'Substract.class.php';
require_once 'Multiplier.class.php';
require_once 'Devider.class.php';
It should be that simple - for future reference you should always order your includes so that dependencies between them can be satisfied, because they get processed in the order you supply them.

Namespaced function not running on PHPUnit test

I'm trying to override a built in php function using a namespaced test like this:
Original Class:
<?php
namespace My\Namespace;
class OverrideCommand
{
public function myFileExists($path)
{
return file_exists($path);
}
}
Unit Test
<?php
namespace My\Namespace\Test\Unit\Console\Command;
function file_exists($path)
{
return true;
}
class OverrideCommandTest extends \PHPUnit_Framework_TestCase
{
/**
* #var OverrideCommand
*/
protected $command;
protected function setUp()
{
$this->command = new \My\Namespace\OverrideCommand();
}
public function testMyFileExists()
{
$result = $this->command->myFileExists('some/path/file.txt');
$this->assertTrue($result);
}
}
In this case the file_exists function in my test should always return true, however when I run PHPUnit I get:
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.
There was 1 failure:
1) My\Namespace\Test\Unit\Console\Command\OverrideCommandTest::testMyFileExists
Failed asserting that false is true.
It's as if the namespaced function is being ignored and it's just calling the built in function instead, am I missing something?
According to your code sample, you define the function file_exists() in the namespace My\Namespace\Test\Unit\Console\Command:
namespace My\Namespace\Test\Unit\Console\Command;
function file_exists($path)
{
return true;
}
so of course, you actually never override the function file_exists() in the root namespace.
As far as I know, you can't do that. Whenever you would try to define a function that already exists, a fatal error will be triggered, see https://3v4l.org/JZHcp.
However, if what you want to achieve is asserting that OverrideCommand::myFileExists() returns true if a file exists, and false if it doesn't, you can do one of the following
Refer to files which do and do not exist in your test
public function testMyFileExistsReturnsFalseIfFileDoesNotExist()
{
$command = new OverrideCommand();
$this->assertTrue($command->myFileExists(__DIR__ . '/NonExistentFile.php');
}
public function testMyFileExistsReturnsTrueIfFileExists()
{
$command = new OverrideCommand();
$this->assertTrue($command->myFileExists(__FILE__);
}
Mock the file system
Use https://github.com/mikey179/vfsStream to mock the file system.
Note: For your example, I would recommend the former.

PHPUnit cannot find source code

I have a PHP project, with the following project structure.
php_test_app
src
Vegetable.php
tests
StackTest.php
VegetableTest.php
The code of these files is shown below. I use PDT and PTI in Eclipse. PHPUnit in Eclipse recognizes that VegetableTest.php belongs to Vegetable.php, because you can toggle between them using the toggle button.
I first try to run the test code by selecting the tests directory in the PHP Explorer and click Run Selected PHPUnit Test. It runs both tests, both the VegetableTest fails with the following trace: Fatal error: Class 'Vegetable' not found in /Users/erwin/Documents/workspace/php_test_app/tests/VegetableTest.php on line 8. A similar issue was posted here: phpunit cannot find Class, PHP Fatal error.
Indeed, I haven't included my source code yet, so now I uncomment the include in VegetableTest.php, shown below. If I now try to run the tests in the same way, PHPUnit does not recognize any test code! Even the StackTest, which is unaltered, is not recognized.
How should I make the include such that the unit tests are
recognized?
Do I need to specify the full path, or just the name of
the file in which the class is defined?
Changing the include statement also doesn't work; I have tried the following.
include 'Vegetable.php';
include 'src/Vegetable.php';
include '../src/Vegetable.php';
Vegetable.php
<?php
// base class with member properties and methods
class Vegetable {
var $edible;
var $color;
function Vegetable($edible, $color="green")
{
$this->edible = $edible;
$this->color = $color;
}
function is_edible()
{
return $this->edible;
}
function what_color()
{
return $this->color;
}
} // end of class Vegetable
// extends the base class
class Spinach extends Vegetable {
var $cooked = false;
function Spinach()
{
$this->Vegetable(true, "green");
}
function cook_it()
{
$this->cooked = true;
}
function is_cooked()
{
return $this->cooked;
}
} // end of class Spinach
StackTest.php
<?php
class StackTest extends PHPUnit_Framework_TestCase
{
public function testPushAndPop()
{
$stack = array();
$this->assertEquals(0, count($stack));
array_push($stack, 'foo');
$this->assertEquals('foo', $stack[count($stack)-1]);
$this->assertEquals(1, count($stack));
$this->assertEquals('foo', array_pop($stack));
$this->assertEquals(0, count($stack));
}
}
?>
VegetableTest.php
<?php
// require_once ('../src/Vegetable.php');
class VegetableTest extends PHPUnit_Framework_TestCase
{
public function test_constructor_two_arguments()
{
$tomato = new Vegetable($edible=True, $color="red");
$r = $tomato.is_edible();
$this->assertTrue($r);
$r = $tomato.what_color();
$e = "red";
$this->assertEqual($r, $e);
}
}
class SpinachTest extends PHPUnit_Framework_TestCase
{
public function test_constructor_two_arguments()
{
$spinach = new Spinach($edible=True);
$r = $spinach.is_edible();
$this->assertTrue($r);
$r = $spinach.what_color();
$e = "green";
$this->assertEqual($r, $e);
}
}
?>
phpunit --bootstrap src/Vegetable.php tests instructs PHPUnit to load src/Vegetable.php before running the tests found in tests.
Note that --bootstrap should be used with an autoloader script, for instance one generated by Composer or PHPAB.
Also have a look at the Getting Started section on PHPUnit's website.

How can i use external class in Codeception?

i created an external class called StringHelper and i putted the require into the _bootstrap.php.
I used it into my acceptance test and it didn't work:
<?php
class StringHelper {
public static function getString($length) {
return "Hello World";
}
}
_bootstrap.php
require_once 'components/StringHelper.php';
My LoginCest.php
<?php
use \AcceptanceTester;
class LoginCest
{
public function test01(AcceptanceTester $I)
{
$I->wantTo('Try to access without permission');
$I->amOnPage('#/list');
$I->waitForText('You don`t have permission.', 10, '.alert');
}
public function test02(AcceptanceTester $I)
{
$I->wantTo(StringHelper::getString(2));
SeleniumHelper::fillField($I, '#desc_login', StringHelper::getString(2));
$I->click("#btn-enter");
$I->waitForText('Please, fill the login field', 10, '.alert');
}
}
My returned message:
Acceptance Tests (2) --------------------------------------------
Trying to Try to access without permission (LoginCest::test01) Ok
Trying to test02 (LoginCest::test02) Ok
Here in "Trying to test02" why doesn't appear "Hello World"?
Try to write a module/helper for this function as codeception queues the commands, so when your command is executed codeception is not "listening".
Refer here: http://codeception.com/docs/06-ModulesAndHelpers

Fatal error: Cannot redeclare class Net_SSH2 in /var/www/phpseclib/Net/SSH2.php on line 194

I have created a CI model that dynamically loads certain classes depending on a parameter that is passed in. These classes are just wrapper classes around phpseclib to make ssh connections to different devices.
What I'm noticing is that when I try to execute one particular method, I'm getting the above error message.
Here's some sample code to help you understand what I'm doing. This is what my model looks like:
public function get_portstatusall($ip, $switchname)
{
$classname = $this->switchToClassName($switchname);
try{
include_once(APPPATH.'libraries/'.$classname.'.php');
$switch_obj = new $classname($ip, 'password', '');
$switch_obj->connect();
$data = $switch_obj->dosomething();
$switch_obj->disconnect();
return $data;
}
catch (Exception $e) {
echo 'this really should be logged...';
return false;
}
}
public function get_portstatusindividual($ip, $switchname)
{
$classname = $this->switchToClassName($switchname);
try{
include_once(APPPATH.'libraries/'.$classname.'.php');
$switch_obj = new $classname($ip, 'password', '');
$switch_obj->connect();
$data = $switch_obj->dosomethingelse();
$switch_obj->disconnect();
return $data;
}
catch (Exception $e) {
echo 'this really should be logged...';
return false;
}
}
As you can see, i'm dynamically determining which class to load depending on the switchname that is passed in. This code successfully loads a class called "device123.php", let's say. Class device123 in turn, instantiates the SSH2 object that comes with the phpseclib, and uses it to send ssh commands to the device.
Here's a clip of code from device 123:
class device123
{
// sample code to demo how to use phpseclib to create an interactive ssh session.
//this library relies on phpseclib. you must include this class and SSH2.php from Net/phpseclib.
private $_hostname;
private $_password;
private $_username;
private $_connection;
private $_data;
private $_timeout;
private $_prompt;
public function __construct($hostname, $password, $username = "", $timeout = 10)
//public function __construct($params)
{
echo 'in the switch constructor<br>';
set_include_path(get_include_path() . PATH_SEPARATOR . '/var/www/phpseclib');
include('Net/SSH2.php');
$this->_hostname = $hostname;
$this->_password = $password;
$this->_username = $username;
} // __construct
public function connect()
{
$ssh = new Net_SSH2($this->_hostname);
if (!$ssh->login($this->_username, $this->_password)) { //if you can't log on...
die("Error: Authentication Failed for $this->_hostname\n");
}
else {
$output= $ssh->write("\n"); //press any key to continue prompt;
$prompt=$ssh->read('/([0-9A-Z\-])*(#)(\s*)/i', NET_SSH2_READ_REGEX);
if (!$prompt) {
die("Error: Problem connecting for $this->_hostname\n");
}
else {
$this->_connection = $ssh;
}
}
} // connect
public function close()
{
$this->_send('exit');
} // close
public function disconnect()
{
$this->_connection->disconnect();
$ssh=NULL;
}
I don't think I quite understand how I can be redeclaring the SSH2 class... but i wanted to see if perhaps I was not destroying / cleaning up after myself properly.
To help troubleshoot, I've tried adding debug echo statements in the constructor and destructor of both the SSH2 class, and also the wrapper class called device123.
It all looks proper...
I don't think I'm on the right track... Can you tell me where you think I should start looking?
Is it because it's possible that both methods are called ... one after the other... and both can possibly load the same class?
Thanks.
Php gives such error when you are trying to load class multiple times like same name class exists in other source file.
All php classes must have unique names. You should include all the files at one place, keep track of all loaded classes if you want a lazy loading, or just use http://cz.php.net/include_once. The same goes for the require function.
The _once postfix does exactly what you need: it prevents the files from loading if it already has been loaded, thus preventing the class redeclaration.

Categories