3

I am following the Testing setup for Slim with PHPUnit @ http://there4development.com/blog/2013/10/13/unit-testing-slim-framework-applications-with-phpunit/

Initially I was having all my logics in the anonymous function

$app->get('/video/', function () use ($app) {
    // all code goes here
}

and testing via PHPUnit worked great...

public function testVideoCountInPage1() {
    $this->get('/video/');
    $this->assertEquals(200, $this->response->status());

    $rawResponse                =   $this->response->body();
    $jsonResponse               =   json_decode($rawResponse);

    $this->assertSame(20, count($jsonResponse->data));
}

But now, I split the core logic in `get('/video/') into multiple functions like this:

$app->get('/video/', function () use ($app) {
    // some logic

    $db                             =   openDB($dbConfig);
    $page                           =   findPageParameter($app->request()->params());

    // some logic
}

function openDB($dbConfig) {
    // open DB here
    return                              $db;
}

function findPageParameter($params) {
    // find page here
    return                              (int)$page;
}

Still I get proper response for calling /video endpoint. But the Unit Tests fail, saying

.PHP Fatal error: Cannot redeclare openDB() (previously declared in /var/www/traffic/app/routes/video.php:69) in /var/www/traffic/app/routes/video.php on line 75

Update: That error got fixed, once I replaced couple of require with require_once. But now assertions in the Tests fails saying

1) videoTest::testVideoCountInPage1
Failed asserting that 404 matches expected 200.

when I call the same end point http://localhost/traffic/index.php/video, I am getting status 200 with the proper results. When the PHPUnit calls the same endpoint, it returns 404

Update 2: The Unit Tests, where I test the individual functions openDB() and findPageParameter() works fine. Only the end-end testing of SLIM REST APIs fail with 404...

Reference:

saiy2k
  • 1,852
  • 1
  • 23
  • 42
  • 2
    You try to declare function more than once, eg. due to multi-including file. If so, use `require/include_once` onstead of `require/include`. – pavel Jul 22 '14 at 05:53
  • You sure that's what your code looks like? The error messages seems to be stating that the `openDB()` function is defined at lines 69 **and** 75 of the same file (`video.php`) – Phil Jul 22 '14 at 05:59
  • @panther thanks it worked :-) @Phil yes, I linked the `video.php` at the bottom But now the assertion fails.. – saiy2k Jul 22 '14 at 06:01

3 Answers3

5

There's a similar answer to a (somewhat) similar question. I'm sure you can find a workaround for the issue, but soon enough you'll be looking how to fix sessions, reset environment configuration, etc., because PHPUnit is a unit testing framework, and units by definition are smaller things than request.

This is area of functional / acceptance testing and there is a fabulous framework called Behat. You should do your own research, but essentially, while PHPUnit is great at testing more or less independent blocks of functionality it sucks at testing bigger things like full request execution. Later you will start experiencing issues with session errors, misconfigured environment, etc., all because each request is supposed to be executed in it's own separate space and you force it into doing the opposite. Behat on the other hand works in a very different way, where for each scenario (post robot, view non-existing page), it sends a fresh request to the server and checks the result. It is mostly used for final testing of everything working together by making assertions on the final result (response object / html / json).

If you want to test your code the proper way consider using the right tools for that. Once you know your way around with Behat you'll fall in love with it + you can use PHPUnit from within the Behat, to make individual assertions.

Community
  • 1
  • 1
Ian Bytchek
  • 8,804
  • 6
  • 46
  • 72
0

That errors occurs when you try to change a function that has already been created.

There must be another file in which the function OpenDB() already has been created, or in the video.php files. That's why Include_once have worked, because the first time you opened de DB it called this function.

From Now on , check all the files included in video.php, and find the other OpenDB() function.

But something tells me that there's already a openDB() in your video.php bfore those lines.

In case you're stuck, copy all the code.

Carnangel
  • 81
  • 8
0

I'm not exactly sure what is going on, but I think you may have a scope problem. When you call the Slim app, the two functions are (openDB, findPageParameter) are global in scope, but I think that when you run them in a unit test, they are part of the unit test class rather than global. The result is the test framework can't find your two functions, you need to pass them explicitly into your app or declare them as globals.

I've actually run into this problem a number of times and discovered it by dumping all the currently scoped objects inside a particular class/function.

If you haven't done it yet, you should dump $rawResponse to see what the actual error message is. My guess is openDB can't be found or some such.

ckm
  • 1,326
  • 10
  • 15