Fake $_SERVER variables in phpUnit - php

I'm still new to phpUnit and I can't make my (very simple) test work.
<?php
use PHPUnit\Framework\TestCase;
class userTest extends TestCase {
public function testTrue() {
$this->assertTrue(true);
// This line wont work without autloader.php
$user = new User();
}
}
The problem is that I need to load all my classes from autoloader.php:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="inc/autoload.php"></phpunit>
But I'n those classes I have a lot of $SERVER variables, like
$_SERVER['REMOTE_ADDR']
$_SERVER['HTTPS']
$_SERVER['SERVER_NAME']
$_SERVER['DOCUMENT_ROOT']
$_SERVER['REQUEST_URI']
This is the error I get:
Notice: Undefined index: REMOTE_ADDR in /Applications/MAMP/htdocs/sakkadentrainer/classes/App.php on line 674
How can I make those variables work? I would prefer to kind of "fake" them as env.variables from the phpunit.xml file, but I don't know if that's possible.
Thanks for you help!
My Setup:
php 7.1.2, phpUnit 6.1.1, macOs Mojave, MAMP
SOLUTION:
https://phpunit.de/manual/6.5/en/appendixes.configuration.html#appendixes.configuration.php-ini-constants-variables

Referring to the Doc, you can Setting PHP INI settings, Constants and Global Variables, as example:
<php>
<server name="REMOTE_ADDR" value="127.0.0.1"/>
</php>
Hope this help

Related

PHPUnit can't find a class loaded in the bootstrap

My problem with PHPUnit is quite simple: if the test class file is included in the bootstrap file, PHPUnit won't be able to find the test class.
You can easily recreate the issue:
The file hierarchy:
./tests/MyTest.php
./bootstrap.php
./phpunit.xml
phpunit.xml
<phpunit bootstrap="./bootstrap.php">
<testsuites>
<testsuite name="MyTest">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
bootstrap.php:
<?php
require __DIR__ .'/vendor/autoload.php';
require __DIR__ .'/tests/MyTest.php';
tests/MyTest.php
<?php
namespace App\Tests;
use PHPUnit\Framework\TestCase;
class MyTest extends TestCase
{
public function testTrue()
{
$this->assertTrue(true);
}
}
In this case, when I run ./vendor/bin/phpunit, it returns "No tests executed!". And if I run ./vendor/bin/phpunit ./tests/MyTest.php, it returns "Class 'MyTest' could not be found in '[...]\tests\MyTest.php'.".
Now, if I remove the second require_once from autoload.php, both commands work as expected.
I've only seen a couple of similar issues on stack. They are six years old and have not been resolved, which makes me think that not allowing this way of loading classes is actually a design choice.
Could you please help me? Thank you!

Class is not found phpunit

I have written phpunit test. I ran it by using following commands:
C:\Program Files (x86)\Ampps\www\phpunit.dev\vendor\bin>phpunit -c ../../phpunit.xml
But end up having this error:
PHP Fatal error: Class 'Acme\SumFinder' not found in C:\Program Files (x86)\Ampps\www\phpunit.dev\tests\AcmeTests\SumFinderTest.php on line 15
I have tried several solutions from these questions:
Class 'sample\question2\Hello' not found with composer and phpunit
Autoloading classes in PHPUnit using Composer and autoload.php
but nothing works. What could be the problem and how am I going to solve it? Thanks!
My directory structures:
phpunit.dev/src/Acme/SumFinder.php
phpunit.dev/tests/AcmeTests/SumFinderTest.php
phpunit.dev/composer.json
phpunit.dev/phpunit.xml
My composer.json written like this:
{
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-4": {
"Acme\\": "./src/"
}
},
"autoload-dev": {
"psr-4": {
"AcmeTests\\": "./tests/"
}
}
}
My Acme\SumFinder.php written like this:
<?php
namespace Acme;
class SumFinder {
private $inputArray;
function __construct($inputArray = null) { ... }
function findSum() { ... }
function compareArrays() { ... }
}
?>
My AcmeTests\SumFinderTest.php:
<?php
namespace AcmeTests;
use Acme\SumFinder;
class SumFinderTest extends \PHPUnit_Framework_TestCase
function testFindSum() { ... }
function testCompareArrays() { ... }
?>
My phpunit.xml config file:
<?xml version="1.0" encoding="utf-8" ?>
<phpunit colors="true" bootstrap="./vendor/autoload.php">
<testsuites>
<testsuite name="First Test">
<directory>./tests</directory>
</testsuite>
</testsuites>
I am using windows 10 and AMPPS stack if it could help solve my problem.
As a general answer: If dumping the optimized autoloader solves your problem, and not optimizing it still shows it, you have a typo somewhere in your directories or file names.
Dumping the optimized autoloader will scan all files it finds in the directory mentioned for PSR-4 or PSR-0 autoloading, and write an array with all class names found, and their corresponding file names. If you made a typo in your path, dumping this array will connect the class name to the correct file path, regardless of any typos.
Note that some file systems (mostly Linux) are case sensitive, others not (Windows), and that cases are relevant for PSR-4 and PSR-0, which would result in the autoloading to work on case-insensitive file systems, but not on case-sensitive ones.
The problem with your question is that none of the information you gave contains an OBVIOUS hint that you were doing something wrong. However, you might have re-typed your code and NOT made the error, while your original code still has the typo in the file path. Double check that.

PHPUnit test error, cannot find class

I'm new in PHPUnit and unit-testing, so I was install PHPUnit and phar via composer and everything had been going fine until I was try to start my simple test. I'm using PhpStorm where I can see all classes were autoload, but when I trying to start my test I got an error:
Fatal error: Class 'PharIo\Manifest\Simple' not found in C:\xampp\htdocs\mydocs\
I don't understand why he is looking for It in folder upper than PHPUnit is exists ?
I was trying to configure autoload section in composer.json and checking settings in phpunit.xml but nothing works.
Add:
I have to reinstall PHPUnit without PharIO, so now I have a little bit of progress, now I have a situation where I can test my class if I make require_once line with a name of the tested class. It looks like:
require_once '../src/Simple.php';
class SimpleTest extends PHPUnit_Framework_TestCase
{
public function testAdd() {
$sum = new Simple();
$this->assertEquals(5, $sum->add(2, 3));
}
}
So my simple class is:
class Simple {
public function add($a, $b) {
return (int) $a + (int) $b;
}
}
But, of course, I want to use namespaces. I try to make some changes based on this question: Autoloading classes in PHPUnit using Composer and autoload.php (I was try even use that repo for test, but an error is still exists) but nothing works for me. I was try to edit my autoload section in the composer.json like this
"autoload": {
"psr-4": {
"app\\": "src/"
}
},
But an error is still exists, another words autoload cannot see It. I was create phpunit.xml and phpunit.dist.xml with a same settings
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xsd"
backupGlobals="true"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./tests/bootstrap.php">
<testsuites>
<testsuite name="The project's test suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
and I made tests/bootstrap.php too with
require_once '../vendor/autoload.php';
I know this is an old question, but maybe you need to do
composer dump-autoload for composer to generate the map of classes.
I wasted 30mins trying to understand why PHPUnit was giving me:
Cannot stub or mock class or interface XXX because it doesn't exists
You should specify the script with autoloading classes.
You can either specify the file with autoloading in XML-file, as suggested in the other answer, or just by specifying --bootstrap option in your command to run tests:
phpunit --bootstrap vendor/autoload.php tests
Composer's autoload relies on configuration located in the vendor/autoload.php file which needs to be loaded at some point in your execution thread. You application already includes this and that's why it works, but the tests use a different entry point so you need to configure it with a file called phpunit.xml.dist.
Assuming your file structure is something like:
app/
src/
tests/
bootstrap.php <- create it in your test folder
vendor/
...
composer.json
composer.lock
phpunit.xml.dist <- create it if does not exist
You can see the various options here, but for a basic config, you can use this.
File phpunit.xml.dist:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xsd"
backupGlobals="true"
backupStaticAttributes="false"
bootstrap="tests/bootstrap.php">
</phpunit>
File tests/bootstrap.php:
require_once '../vendor/autoload.php';
You should run phpunit from the root.

PHPUnit in a legacy environment

I'm starting to setup PHPUnit (v4.8) to be used in my 'legacy' code (it's not so legacy, but it have bad programming practices).
The structure of my folders is as follows
/home
-phpunit.xml
/folder1
/folder2
/folder3
/vendor
/tests
-Test1.php
/includes
-functions.php
/libs
-User.php
-TableClass.php
....
functions.php
<?php
//require_once $_SERVER['DOCUMENT_ROOT'] . "/home/vendor/autoload.php" ;
require_once $_SERVER['DOCUMENT_ROOT'] . "/home/includes/libs/table_classes/User.php" ;
?>
I have commented that line, because I think composer automatically loads it. Question 1, Am I Rigth? (because phpunit get automatically recognized inside my Test class...)
Test1.php
<?php
class Test1 extends PHPUnit_Framework_TestCase
{
public function testSomething()
{
// $something = getColNameByStatusId(1);
$this->assertEquals(1,2);
}
}
?>
phpunit.xml
<phpunit bootstrap="includes/functions.php" colors="true">
<testsuite name="Test1" >
<directory>./tests</directory>
</testsuite>
</phpunit>
Then I Execute phpunit in command line
My functions.php works fine in my code, of course with no composer integration, but when It's loaded with phpunit it 'breaks', I get the following error:
Warning: require_once(/home/includes/libs/table_classes/User.php): failed to open stream: No such file or directory in C:\wamp\www\home\includes\functions.php on line 18
I think I'm missing the 'loading' stuff for phpunit. My code doesn't use namespaces and PSR-0 neither PSR-4.
Question 2- How to properly load files in this case?
My goal is to load functions.php then it will load all other 'table' classes for doing my tests
Replace $_SERVER['DOCUMENT_ROOT'] with __DIR__ and adjusted the paths accordingly, and everything worked fine.
PHPUnit does not set $_SERVER['DOCUMENT_ROOT'] so It was not finding my files. Apache's do that. So the CLI of PHPUnit couldn't find it.
Hope it helps someone else.
I think it is better to start using PHPUnit by running
phpunit --generate-configuration
and follow some simple questions.
To autoload 'functions.php' and other table 'classes', you may try via composer.json autoload.
"autoload": {
"psr-4": {
"Model\\": "libs/"
}
}
Here is the link with autoload for your reference.

Can't extend PHPUnit_Extensions_Database_TestCase

I had become totally convinced about TDD and trying to use it by the book, looking forward to have a near to 100% test coverage and always writing tests before new coding.
I'm using phpUnit over ZF and although I can feel some progress somedays, in others I feel like I'm totally stuck.
My application is very database centric and I am in need to begin to test (and code...) database persistence.
I was taking a look at slides from Testing Lamp Appplications Presentation by Stephenn Bergmann and it seems very clear and straightforward how to test database interaction.
But, always I try to use a class that extends PHPUnit_Extensions_Database_TestCase I have error messages about not finding some class at 'PHPUnit_Extensions_Database' namespace.
Probably I´m missing some crucial point, as I have the same problem when I try to follow any of others solutions and suggestions I can find, like an answer and a presentation that I can't link here because of my reputation...
In all cases, when I extends Database_TestCase, some class is not found.
I suspect that there is something related with the way I'm bootstraping, but I can't find what I'm doing wrong. The tests I wrote that extend ControllerTestCase work well.
I'm running over Xampp. phpUnit version os 3.6.10, php is 5.3.8, Zend Framework is 1.11.11
I'm using the following phpunit.xml as php configuration:
<phpunit bootstrap="./application/bootstrap.php" colors="true">
<testsuite name="Some">
<directory>./</directory>
</testsuite>
<filter>
<whitelist>
<directory suffix=".php">../application/</directory>
<directory suffix=".php">../library/MyApp/</directory>
<exclude>
<directory suffix=".phtml">../application/</directory>
<file>../application/Bootstrap.php</file>
<file>../application/modules/default/controllers/ErrorController.php</file>
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="./log/report" charset="UTF-8" yui="true" hightlight="true" lowupperbound="50" highlowerbound="80">
<log type="testdox" target="./log/testdox.html">
</log></log></logging>
My Bootstrap.php is:
error_reporting(E_ALL | E_STRICT);
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
require_once 'Zend/Application.php';
require_once 'ControllerTestCase.php';
and ControllerTestCase.php
require_once 'Zend/Application.php';
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';
class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
/**
* #var Zend_Application
*/
protected $application;
public function setUp() {
$this->bootstrap = array($this, 'appBootstrap');
parent::setUp();
}
public function appBootstrap() {
$this->application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
$this->application->bootstrap();
}
}
And when I create a Test as, for exemple, this tryTest.php
require_once 'PHPUnit/Extensions/Database/TestCase.php';
class TryTest extends PHPUnit_Extensions_Database_TestCase {
/*** any test or even just getConnection ***/
}
I receive the following error message or something close to it in other ways I try:
Fatal error: Class 'PHPUnit_Extensions_Database_DefaultTester' not found in C:\xampp\php\PEAR\PHPUnit\Extensions\Database\TestCase.php on
line 132
Call Stack:
0.0003 326968 1. {main}() C:\xampp\php\phpunit:0
0.0141 745152 2. PHPUnit_TextUI_Command::main() C:\xampp\php\phpunit:46
0.0141 745568 3. PHPUnit_TextUI_Command->run() C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:130
0.4012 5280032 4. PHPUnit_TextUI_TestRunner->doRun() C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:192
0.7182 5750296 5. PHPUnit_Framework_TestSuite->run() C:\xampp\php\PEAR\PHPUnit\TextUI\TestRunner.php:325
2.4058 11441872 6. PHPUnit_Framework_TestSuite->run() C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:705
2.4060 11442104 7. PHPUnit_Framework_TestSuite->runTest() C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:745
2.4060 11442104 8. PHPUnit_Framework_TestCase->run() C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:772
2.4061 11442104 9. PHPUnit_Framework_TestResult->run() C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:751
2.4066 11441136 10. PHPUnit_Framework_TestCase->runBare() C:\xampp\php\PEAR\PHPUnit\Framework\TestResult.php:649
2.4079 11494800 11. PHPUnit_Extensions_Database_TestCase->setUp()
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:801
2.4080 11494832 12. PHPUnit_Extensions_Database_TestCase->getDatabaseTester()
C:\xampp\php\PEAR\PHPUnit\Extensions\Database\TestCase.php:202
2.4080 11494832 13. PHPUnit_Extensions_Database_TestCase->newDatabaseTester()
C:\xampp\php\PEAR\PHPUnit\Extensions\Database\TestCase.php:92
There is a DefaultTester.php at C:\xampp\php\PEAR\PHPUnit\Extensions\Database and I can't figure out what is going on...
I got to this configuration after following this [Zendcast from Jon Lebensold][2]. At that moment, I had some hard times trying to solve some problems, but after some help from #edorian I found that the main problem was between my chair and keyboard... :-/ Probably same situation now...
I even tryed to create a MapperTestCase in a similar way as Jon built his ControllerTestCase.php file, but this didn't help me anyhow.
So, now I'm here, trying to get some help to find what is wrong with my environment or approach.
Not really sure if it has solved all problems, but searching at Stackoverflow, I´d find this question that reported something similar to mine:
require_once 'Zend/Loader/AutoLoader.php';
$autoloader = Zend_Loader_AutoLoader::getInstance();
$autoloader->registerNamespace('PHPUnit_');
When I tried to put the code above at my bootstrap.php, I could at least make $connection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, 'mydb'); works
I still can't understand why PHPUnit extensions weren't being find, but, at least I will can advance...

Categories