Laravel 4 - Unit Tests

丶灬走出姿态 提交于 2019-12-11 08:16:01

问题


I am trying to write unit tests for my application, I think I know how to test a GET request for example; The controller I am testing has the following function, which is supposed to get the 'account create view'

public function getCreate() {
    return View::make('account.create');
}

Also, this is referenced in the routes file like this

/*
Create account (GET)
*/
Route::get('/account/create', array(
    'as'  =>  'account-create',
    'uses'  =>  'AccountController@getCreate'
));

and what I am doing for testing looks like this:

public function testGetAccountCreate()
{ 
  $response = $this->call('GET', '/account/create');

  $this->assertTrue($response->isOk()); 

  $this->assertResponseOk();
}

Now this test passes, but what if I want to test the POST request? The post function I want to test is the following:

    public function postCreate() {
    $validator = Validator::make(Input::all(),
        array(
            'email'           => 'required|max:50|email|unique:users',
            'username'        => 'required|max:20|min:3|unique:users',
            'password'        => 'required|min:6',
            'password_again'  => 'required|same:password'
        )
    );

    if ($validator->fails()) {
        return Redirect::route('account-create')
                ->withErrors($validator)
                ->withInput();
    } else {

        $email    = Input::get('email');
        $username = Input::get('username');
        $password = Input::get('password');

        // Activation code
        $code     = str_random(60);

        $user = User::create(array(
            'email' => $email,
            'username' => $username,
            'password' => Hash::make($password),
            'password_temp' => '',
            'code'  => $code,
            'active'  => 0
        ));

        if($user) {

            Mail::send('emails.auth.activate', array('link' => URL::route('account-activate', $code), 'username' => $username), function($message) use ($user) {
                $message->to($user->email, $user->username)->subject('Activate your account');
            });

            return Redirect::route('account-sign-in')
                  ->with('global', 'Your account has been created! We have sent you an email to activate your account.');
        }
    }
}

This is also referenced in routes file like this:

  /*
  Create account (POST)
  */
  Route::post('/account/create', array(
      'as'  =>  'account-create-post',
      'uses'  =>  'AccountController@postCreate'
  ));

I have tried to write the following test but no success. I am not sure what is going wrong, I think its because this needs data and i am not passing them in correctly? Any clue to get started with unit tests, appreciated.

public function testPostAccountCreate()
{
$response = $this->call('POST', '/account/create');
$this->assertSessionHas('email');
$this->assertSessionHas('username');
$this->assertSessionHas('email');
}

The output of the test is:

There was 1 failure:

1) AssetControllerTest::testPostAccountCreate
Session missing key: email
Failed asserting that false is true.

/www/assetlibr/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:271
/www/assetlibr/app/tests/controllers/AssetControllerTest.php:23

回答1:


Make sure that the route filters and sessions are enabled in the setUp function :

public function setUp()
{
    parent::setUp();

    Session::start();

    // Enable filters
    Route::enableFilters();
}  

E.g. test login :

public function testShouldDoLogin()
{
// provide post input

$credentials = array(
        'email'=>'admin',
        'password'=>'admin',
        'csrf_token' => csrf_token()
);

$response = $this->action('POST', 'UserController@postLogin', null, $credentials); 

// if success user should be redirected to homepage
$this->assertRedirectedTo('/');
}



回答2:


You haven't actually said what no success looks like, but if it's that your assertions are failing, then that would be because your code doesn't place any data into the session, so those assertions would fail even if you were passing data with your post request.

To pass that data you would add a third parameter to the call() method, something like this:

public function testPost()
{
    $this->call('POST', 'account/create', ['email' => 'foo@bar.com']);

    $this->assertResponseOk();

    $this->assertEquals('foo@bar.com', Input::get('email'));
}

though in practice I'd recommend that you test for appropriate outcomes ie. redirects and mail sent depending upon the input data, rather than examining the passed data.



来源:https://stackoverflow.com/questions/22482943/laravel-4-unit-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!