Php test if headers sent

Test PHP headers with PHPUnit

You should of course add methods for setcookie, headers_sent and any other functions which issue HTTP headers. Solution 1: The issue is that PHPUnit will print a header to the screen and at that point you can’t add more headers.

Test PHP headers with PHPUnit

I’m trying to use PHPunit to test a class that outputs some custom headers.

The problem is that on my machine this:

assertContains('Location: foo', $headers_list); > > 
name@host [~/test]# phpunit --verbose HeadersTest.php PHPUnit 3.6.10 by Sebastian Bergmann. E Time: 0 seconds, Memory: 2.25Mb There was 1 error: 1) HeadersTest::testHeaders Cannot modify header information - headers already sent by (output started at /usr/local/lib/php/PHPUnit/Util/Printer.php:173) /test/HeadersTest.php:9 FAILURES! Tests: 1, Assertions: 0, Errors: 1. 

This looks as if there is something else outputting to the terminal before the test runs even though there is no other file included and there is no other character before the beginning of the PHP tag. Could it be something inside PHPunit that is causing this?

What could the issue be?

The issue is that PHPUnit will print a header to the screen and at that point you can’t add more headers.

The work around is to run the test in an isolated process. Here is an example

$ phpunit FooTest.php PHPUnit 3.6.10 by Sebastian Bergmann. . Time: 1 second, Memory: 9.00Mb OK (1 test, 0 assertions) 

The key is the @runInSeparateProcess annotation.

Читайте также:  Примеры в корзину javascript

If you are using PHPUnit ~4.1 or something and get the error:

PHP Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in -:378 Stack trace: #0 thrown in - on line 378 Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 Call Stack: 0.0013 582512 1. () -:0 

Try add this to your bootstrap file to fix it:

Although running the test in a separate process does fix the problem, there’s a noticeable overhead when running a large suite of tests.

My fix was to direct phpunit’s output to stderr, like so:

That should fix the problem, and it also means that you don’t have to create a wrapper function and replace all occurrences in your code.

As an aside: For me headers_list() kept returning 0 elements. I noticed @titel’s comment on the question and figured it deserves special mention here:

Just wanted to cover this if there are some other people interested in this as well. headers_list() doesn’t work while running PHPunit (which uses PHP CLI) but xdebug_get_headers() works instead.

As already mentioned in a comment, I think it’s a better solution to define processIsolation in the XML config file like

Like this, you don’t have to pass the —stderr option, which might irritate your co-workers.

Php — Unit Testing with items that need to send headers, The best thing you can do, is to isolate the side-effects in a component, that can be swapped at runtime. That way, your tests can use mocked objects, while the

How to PHP : Test PHP headers with PHPUnit

How to PHP : Test PHP headers with PHPUnit [ Ext for Developers : https://www.hows.tech/p
Duration: 1:17

How to test for expected headers?

I have a unit test that fails because headers are already sent. However, the header in this scenario is expected.

How do I tell PHPUnit to expect a 500 header?

I’ve read this question but it didn’t help.

The method is wrapped inside an output buffer.

ob_start(); $foo->methodWhichSendsHeader(); ob_clean(); 

If you have xdebug installed you can use xdebug_get_headers() to get the headers. Then you can test them as needed.

$headers=xdebug_get_headers(); 

gets you an array which looks like.

array( 0 => "Content-type: text/html", 1 => . ) 

So you’ll need to parse each header line to separate the header name from the value

If you can’t use xdebug_get_headers on your system, another approach is to mock the header function.

I’m using the following now, which works great. Lets say you have this code.

I replace header with a header function which is testable like this.

The Testable class is implemented as follows. Note that functions just need to be prepended with Testable:: . Otherwise they work just the same as the usual functions.

class Testable < private static $headers=array(); static function header($header) < if (defined('UNIT_TESTING')) < self::$headers[]=$header; >else < header($header); >> public static function reset() < self::$headers=array(); >public static function headers_list() < if (defined('UNIT_TESTING')) < return self::$headers; >else < return headers_list(); >> > 

Now all you need to do is define UNIT_TESTING in your tests, but not in production. Then when you come to test your headers, just call Testable::headers_list() .

You should of course add methods for setcookie, headers_sent and any other functions which issue HTTP headers.

Another possible approach is to override the header php function for the namespace you are testing. https://www.codepunker.com/blog/overwrite-built-in-php-functions-using-namespaces

namespace My\Application\Namespace; use My\Test\Application\Namespace; //this overrides the header function for that namespace //it works only if the function is called without the backslash function header($string) < HeaderCollector::$headers[] = $string; >namespace My\Test\Application\Namespace /** * Class HeaderCollector * Using this in combination with function header override * for the namespace My\Application\Namespace * we can make assertions on headers sent */ class HeaderCollector < public static $headers = []; //call this in your test class setUp so headers array is clean before each test public static function clean() < self::$headers = []; >> 
namespace My\Test\Application\Namespace use PHPUnit\Framework\TestCase; class MyTest extends TestCase < protected function setUp() < parent::setUp(); //clean for each test HeaderCollector::clean(); >public function testHeaders() < //call the code that send headers . self::assertEquals( ["Content-Type: text/html; charset=UTF-8", "Another-Header. "], HeaderCollector::$headers ); >> 

You can keep your code clean and you don’t need xdebug

Header getting dropped in Laravel/PHPUnit Testing, Headers are the 3rd parameter not the 2nd. Try changing you’re PUT request to be: $content = $this->put(‘users/xsettings/0’,

Unit Testing with items that need to send headers

I’m currently working with PHPUnit to try and develop tests alongside what I’m writing, however, I’m currently working on writing the Session Manager, and am having issues doing so.

The constructor for the Session handling class is

private function __construct() < if (!headers_sent()) < session_start(); self::$session_id = session_id(); >> 

However, as PHPUnit sends out text before it starts the testing, any testing on this Object returns a failed test, as the HTTP «Headers» have been sent.

Well, your session manager is basically broken by design. To be able to test something, it must be possible to isolate it from side effects. Unfortunately, PHP is designed in such a way, that it encourages liberal use of global state ( echo , header , exit , session_start etc. etc.).

The best thing you can do, is to isolate the side-effects in a component, that can be swapped at runtime. That way, your tests can use mocked objects, while the live code uses adapters, that have real side-effects. You’ll find that this doesn’t play well with singletons, which I presume you’re using. So you’ll have to use some other mechanism for getting shared objects distributed to your code. You can start with a static registry, but there are even better solutions if you don’t mind a bit of learning.

If you can’t do that, you always have the option of writing integration-tests. Eg. use the PHPUnit’s equivalent of WebTestCase .

Create a bootstrap file for phpunit, which calls:

Then start phpunit like this:

phpunit --bootstrap pathToBootstrap.php --anotherSwitch /your/test/path/ 

The bootstrap file gets called before everything else, so the header hasn’t been sent and everything should work fine.

phpUnit prints output as the tests run thus causing headers_sent() to return true even in your first test.

To overcome this issue for an entire test suite you simply need to use ob_start() in your setup script.

For example, say you have a file named AllTests.php that is the first thing loaded by phpUnit. That script might look like the following:

addTest(YourFramework_AllTests::suite()); return $suite; > > 

I had the same issue and I solved it by calling phpunit with —stderr flag just like this:

phpunit --stderr /path/to/your/test 

Setting HTTP headers to be able to run test cases, You cannot catch headers using PHPUnit 3 if you’re using testdox or something like that. I forget which one, but one of the formatters was bugged when I

Источник

headers_sent

Нельзя отправить дополнительные строки заголовков, используя функцию header() если заголовки уже были отправлены. Используя эту функцию, можно предупредить ошибки, связанные с HTTP заголовками. Также можно использовать буферизацию вывода.

Список параметров

Если опциональные параметры file и line установлены, то функция headers_sent() поместит имя файла PHP исходника и номер строки, с которой начинается вывод, в переменные file и line .

Номер строки, с которой начинается вывод.

Возвращаемые значения

Функция headers_sent() вернет FALSE если HTTP заголовки не были отправлены, либо TRUE если отправлены.

Примеры

Пример #1 Пример использования headers_sent()

// Если не было отправлено ни одного заголовка, то отправить один
if (! headers_sent ()) header ( ‘Location: http://www.example.com/’ );
exit;
>

// Пример использования необязательных параметров file и line, как в PHP 4.3.0
// необходимо отметить, что $filename и $linenum передаются для дальнейшего использования.
// Не назначайте их значения заранее.
if (! headers_sent ( $filename , $linenum )) header ( ‘Location: http://www.example.com/’ );
exit;

// Скорее всего, ошибка будет происходит здесь.
> else

Примечания

Замечание:

Доступ к заголовкам и их вывод будет осуществляться только в случае, если в используемом вами SAPI есть их поддержка.

Смотрите также

  • ob_start() — Включение буферизации вывода
  • trigger_error() — Вызывает пользовательскую ошибку/предупреждение/уведомление
  • headers_list() — Возвращает список переданных (или готовых к передаче) заголовков
  • См. информацию по функции header() — Отправка HTTP заголовка для более детальной информации.

Источник

Оцените статью