Laravel 4 - 单元测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22482943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:12:54  来源:igfitidea点击:

Laravel 4 - Unit Tests

testinglaravellaravel-4

提问by cch

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'

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

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:

现在这个测试通过了,但是如果我想测试 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.');
        }
    }
}

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

回答by petercoles

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:

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

public function testPost()
{
    $this->call('POST', 'account/create', ['email' => '[email protected]']);

    $this->assertResponseOk();

    $this->assertEquals('[email protected]', 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.

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

回答by cenob8

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

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

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