PHPUnit Class not found even though it is defined - php

I'm trying to unit-test my class-function using PHPUnit, but I keep running into Class not found error, even though it is present.
Here's my func.php where the class is defined:
<?php
class func {
public function url($var) {
//do something
return myvalue;
}
?>
And here's funcCase.php where the Test class is defined:
<?php
require 'func.php';
require 'PHPUnit.php';
class funcTest extends PHPUnit_TestCase {
// contains the object handle of the string class
var $box;
// constructor of the test suite
function funcTest($name) {
$this->PHPUnit_TestCase($name);
}
// called before the test functions will be executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function setUp() {
// create a new instance of String with the
// string 'abc'
$this->box = new func();
}
// called after the test functions are executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function tearDown() {
// delete your instance
unset($this->box);
}
// test the url
function testurl() {
$result = $this->box->url('myvalue');
$expected = 'myvalue';
echo $result;
$this->assertTrue($result == $expected);
}
}
?>
And the funcTest.php which runs the PHPTestSuite:
<?php
require_once 'funcCase.php';
require_once 'PHPUnit.php';
$suite = new PHPUnit_TestSuite("funcTest");
$result = PHPUnit::run($suite);
echo $result -> toString();
?>
When running the funcTest.php using phpunit funcTest.php I get this error:
TestCase funcTest->testurl() failed: expected TRUE, actual FALSE
Class 'funcTest' could not be found in 'C:\xampp\htdocs\funcTest.php'.
Why am I getting this if the funcTest class is defined and funcCase.php is included in funcTest.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.

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.

using same namespace php, Call to undefined function

using same namespace php
I have this files in the same folder :
OtherFunctions.php
<?php
namespace Pack\sp;
$Tble = NULL;
function SetTble($tble) {
global $Tble;
$Tble = $tble;
}
function GetTble() {
global $Tble;
return $Tble;
}
function Funct0($Str0, $Str1) {
return $Str0 == $Str1;
}
function Funct1($Arg) {
return "The Value is ".$Arg;
}
//... from 0 to 16
function Funct16($Arg) {
return "The Value is ".$Arg;
}
?>
How to call all functions contained in this file?
In one class File SubClass.php I have this:
<?php
namespace Pack\sp;
class SubClass {
public $CArg = "";
}
?>
In other class File LeadClass.php
I have this:
<?php
namespace Pack\sp;
use \Pack\sp\SubClass;
require_once("OtherFunctions.php");
class LeadClass {
public function __construct($Name) {
echo("_._");
$NewSC = new SubClass();
$NewSC->CArg = $Name;
SetTble($Name);
echo("ini:".GetTble().":end");
}
}
?>
I want call all function in one instruction of OtherFunctions.php File, but I don't kno how to do it....
I trying to replicate this message in other code
Fatal error: Call to undefined function GetTble() in C:...\LeadClass.php on line 10
But, I'm obtaining blank page
EDIT
Was added the line:
require_once("OtherFunctions.php");
And was replaced the line:
require_once("SubClass.php");
by the line:
use \Pack\sp\SubClass;
in LeadClass.php File.
But, I'm obtaining blank page
You need to add the next line
namespace Pack\sp;
use \Pack\sp\SubClass; // <--- add this
Also I think you should put the functios of the OtherFunctions file into a new class link
namespace Pack\sp;
class OtherFunctions{
// your current code goes here
}
After that you need to extend the SubClass whit the OtherFunctios class
namespace Pack\sp;
use Pack\sp\OtherFunctions;
class SubClass extends OtherFunctions {
public $CArg = "";
}
EDIT
I just tried your code and I can make the LeasClass to work as follow
<?php
namespace Pack\sp;
require_once("OtherFunctions.php");
require_once("SubClass.php");
class LeadClass {
public function __construct($Name) {
echo("_._");
$NewSC = new SubClass();
$NewSC->CArg = $Name;
SetTble($Name);
echo("ini:".GetTble().":end");
}
}
$LeadClass = new LeadClass('table');
?>
Have you already initialize the class?

PHPunit test not mocking dependencies

I am attempting to use PHPunit to mock out some dependencies, but my mock objects don't seem to be working.
Logger.php
class Logger
{
function __construct($log_path)
{
// make sure file exists, open file handle
}
function write($msg)
{
// write message to log
}
}
MyCurl.php
class MyCurl
{
function __construct($url)
{
// set my default curl options
}
function exec()
{
// execute curl request and capture output
}
}
function_x.php
require_once("Logger.php");
require_once("MyCurl.php");
function function_x($params)
{
// set some stuff up;
$LoggerObj = new Logger($filepath);
$CurlObj = new MyCurl($url);
// more stuff
$LoggerObj->write($CurlObj->exec());
// do stuff
return $result;
}
function_x_Test.php
require_once('function_x.php');
class functionXTest extends PHPUnit_Framework_TestCase
{
public function testCleanRun()
{
$MockLogger = $this->getMockBuilder('Logger')->disableOriginalConstructor()->setMethods(array('write', '__destruct'))->getMock();
$MockLogger->expects($this->any())->method('write')->will($this->returnValue(true));
$MockCurl = $this->getMockBuilder('MyCurl')->disableOriginalConstructor()->setMethods(array('exec', '__destruct'))->getMock();
$MockCurl->expects($this->any())->method('exec')->will($this->returnValue('exec returnz'));
$result = function_x($params);
// start assertions with function_x results
}
}
When I run my test, it shows that the original constructor is being called for my Logger class. It does not seem to be using the mocked class. I assumed that if I declared the mock in the test that all calls to the original class would be mocked, thus eliminating those dependencies. Clearly, I am doing something wrong. Can anyone either lend me a helping hand or point me in the right direction? Thanks!
Mocking is replacing an object (see documentation), not a class.
So, to get your example working with mocks, you should inject the objects (dependency injection):
function function_x($params, $logger = null, $curl = null)
{
//Here, you can set logger and curl if they are null.
// only do this to make sure legacy code works.
if(!$logger) {
$logger = new Logger();
}
if(!$curl) {
$curl = new MYCurl();
}
//rest of your code
}
and in your test, you call
require_once('function_x.php');
class functionXTest extends PHPUnit_Framework_TestCase
{
public function testCleanRun()
{
$MockLogger = $this->getMockBuilder('Logger')->disableOriginalConstructor()->setMethods(array('write', '__destruct'))->getMock();
$MockLogger->expects($this->any())->method('write')->will($this->returnValue(true));
$MockCurl = $this->getMockBuilder('MyCurl')->disableOriginalConstructor()->setMethods(array('exec', '__destruct'))->getMock();
$MockCurl->expects($this->any())->method('exec')->will($this->returnValue('exec returnz'));
$result = function_x($params, $MockLogger, $MockCurl);
// start assertions with function_x results
}
}

How to share a dynamic variable between files in PHP(5)?

I have an object of some class that obeys the singleton pattern. I need to initialize it in one file and then use it in others. I don't know how to do this, here is what I tried :
//myClass.php
class myClass
{
private static $instance = null;
private function __construct($args)
{
//stuff
}
public function Create($args)
{
self::$instance = new myClass($args);
return self::$instance;
}
public function Get()
{
return self::$instance;
}
}
//index.php
<?php
require_once('myClass.php');
$instance = myClass::Create($args);
?>
Test Me!
//test.php
echo(is_null(myClass::Get())); //displays 1
So the problem is that from test.php, myClass::get() always returns null!
I have also tried to store the instance in the $_SESSION, which gives me the same result. Can you please point me in the right direction?
You should include file with the class difinition in each file where it used (and it should be included before it will in use).
<?php // filename: test.php
include_once("myClass.php");
$oClassInstance = myClass::Get();
var_dump($oClassInstance);
BTW
You don't need to define those two methods Create and Get. You can create only one method called getInstance:
// only one instance of the class
private static $_oInstance = null;
public static function getInstace()
{
if (!self::$_oInstance)
{
self::$_oInstance = new self();
}
return self::$_oInstance;
}
And then you can use it like:
<?php // filename: index.php
include_once("myClass.php");
// if instance does not exist yet then it will be created and returned
$oClass = myClass::getInstace();
<?php // filename: test.php
include_once("myClass.php");
// the instance already created and stored in myClass::$_oInstance variable
// so it just will be returned
$oClass = myClass::getInstance();
UPD
If you have to put some arguments into constructor just use predefined arguments:
private function __construct($aArg)
{
// this code will be launched once when instance is created
// in the any other cases you'll return already created object
}
public static function getInstance($aArgs = null)
{
if (!self::$_oInstance)
{
self::$_oInstance = new self($aArgs);
}
return self::$_oInstance;
}
ANSWER
Sorry that you have to scroll a few screens to find this =)))
The reason why you can't use myClass::Get() in you context is that you have 2 scripts that means - two different programs.
Singleton should be used within a single application (one script).
So in your case, correct usage will be module system:
- index.php
- main.php
- test.php
// file: index.php
include_once "myClass.php"
$module = $_GET["module"];
include_once $module ".php";
// file: main.php
$oClass = myClass::Create($someArgs);
var_dump($oClass); // you'll see you class body
// file: test.php
$oClass= myClass::Get();
var_dump($oClass); // you'll see the same class body as above
And your links will be:
index.php?module=main
index.php?module=test
The Create() function need to check whether $instance property already has a value before creating a new object. For example
public function Create()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
In test.php you can just call myClass::Create(), no need to have the Get() function at all

Categories