Laravel 4 - 单元测试

时间:2014-03-18 14:52:34

标签: testing laravel laravel-4

我正在尝试为我的应用程序编写单元测试,我想我知道如何测试GET请求; 我正在测试的控制器具有以下功能,该功能应该是“帐户”创建视图'

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

此外,这在路径文件中引用,如

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

我正在做的测试是这样的:

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

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

  $this->assertResponseOk();
}

现在这个测试通过,但如果我想测试POST请求怎么办? 我要测试的post函数如下:

    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.');
        }
    }
}

这也在路由文件中引用,如下所示:

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

我曾尝试编写以下测试但没有成功。我不确定会出现什么问题,我认为这是因为这需要数据并且我没有正确传递它们?感谢开始进行单元测试的任何线索。

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

测试的输出是:

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

2 个答案:

答案 0 :(得分:3)

你实际上没有说过什么都没有成功,但如果你的断言失败了,那就是因为你的代码没有将任何数据放入会话中,所以即使你是这样的话,这些断言也会失败用你的帖子请求传递数据。

要传递该数据,您需要在call()方法中添加第三个参数,如下所示:

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

    $this->assertResponseOk();

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

虽然在实践中我建议你测试适当的结果,即。根据输入数据重定向和发送邮件,而不是检查传递的数据。

答案 1 :(得分:3)

确保在setUp函数中启用了路由过滤器和会话:

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

    Session::start();

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

E.g。测试登录:

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('/');
}