1

I am trying to test some of my controllers through Unit Testing. But there is something strange happening. With the following code in my testcase:

public function test_username_registration_too_short()
{
    $result = $this->action('POST', 'App\\Controllers\\API\\UserController@store', null, [
        'username' => 'foo'
    ]);
    $this->assertEquals('not_saved', $result->getContent());

// $result = $this->action('POST', 'App\\Controllers\\API\\UserController@store', null, [
//      'username' => 'foo'
// ]);
// $this->assertEquals('not_saved', $result->getContent());
}

public function test_username_registration_too_short_run_2()
{
    $result = $this->action('POST', 'App\\Controllers\\API\\UserController@store', null, [
        'username' => 'foo'
    ]);
    $this->assertEquals('not_saved', $result->getContent());
}

When I run this, the initial too_short test passes, but the exact same code on run 2 does not pass (it even manages to save the user). But if I put that same code twice in the same method (what is commented out now) it works perfectly? I have nothing in my setUp or tearDown methods. And I am a bit lost here.

The code in the controller is the following:

$user = new User(Input::all());
if($user->save())
{
    return 'saved';
}
return 'not_saved';
Matthijn
  • 3,126
  • 9
  • 46
  • 69

1 Answers1

2

I'm not going to stop repeating myself over this question. There's a similar answer to a (somewhat) similar question. TL;DR: don't use unit testing framework for functional / integration testing.

This is area of functional 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
  • 2
    But if this is not made for that, why does the documentation of Laravel show exactly what I am doing? http://laravel.com/docs/testing#refreshing-the-application on my search across the web I did stumble upon Behat but I thought, well first lets just try the "Laraval" documented way. – Matthijn Sep 16 '14 at 14:05
  • 1
    I know. The truth is your you can say that your entire application is a unit in a certain context, and you can use unit testing practices to do the testing. Sometimes it's acceptable, but most of the times it's a bad idea. Acceptable would be when your actions are simple (don't have much logic, don't use sessions, i.e., can be run more than once without causing problems). In such situations PHPUnit would be a simpler and much faster solution for running **simulated** requests. But to properly test the complete functionality chunks (request / response) you need a proper tool for that. – Ian Bytchek Sep 16 '14 at 14:13
  • If you have future questions on Behat / Mink, check out the [relevant tags](http://stackoverflow.com/questions/tagged/behat+or+mink) or ask your own, there's plenty of support around. – Ian Bytchek Sep 16 '14 at 14:16
  • 1
    I went with [codeception](http://codeception.com) instead of Behat. The idea is the same, the execution is a bit different. Thanks for the push in the right direction. – Matthijn Sep 17 '14 at 11:59
  • Good! Codeception is a great frameworks. The matter of choice ;) – Ian Bytchek Sep 17 '14 at 12:17