6

我正在使用 phpunit 和 mockery 在 laravel 中学习单元测试。我目前正在尝试测试 UsersController::store()。

我正在嘲笑用户模型并使用它来测试索引方法,这似乎有效。当我取出 $this->user->all() 测试失败并且它通过时。

在测试 store 方法时,虽然我使用模拟来测试用户模型是否收到 validate() 一次。store 方法为空,但测试通过。为简洁起见,我省略了课程中不相关的部分

<?php

class UsersController extends BaseController {

    public function __construct(User $user)
    {
        $this->user = $user;
    }
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $users = $this->user->all();

        return View::make('users.index')
        ->with('users', $users);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        return View::make('users.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return Response
     */
    public function store()
    {
        //
    }

}

用户控制器测试.php

<?php
    use Mockery as m;
class UserControllerTest extends TestCase {

    public function __construct()
    {
        $this->mock = m::mock('BaseModel', 'User');
    }

    public function tearDown()
    {
        m::close();
    }

    public function testIndex()
    {
        $this->mock
            ->shouldReceive('all')
            ->once()
            ->andReturn('All Users');
        $this->app->instance('User', $this->mock);
        $this->call('GET', 'users');
        $this->assertViewHas('users', 'All Users');
    }

    public function testCreate()
    {
        View::shouldReceive('make')->once();
        $this->call('GET', 'users/create');
        $this->assertResponseOk();
    }

    public function testStore()
    {

        $this->mock
            ->shouldReceive('validate')
            ->once()
            ->andReturn(m::mock(['passes' => 'true']));
        $this->app->instance('User', $this->mock);
        $this->call('POST', 'users');
    }


}
4

3 回答 3

15

Mockery 默认是一个存根库,而不是一个模拟库(因为它的名字而令人困惑)。

这意味着->shouldReceive(...)默认情况下是“零次或多次”。使用时->once(),你说它应该被调用零次或一次,但不能更多。这意味着它总会过去。

当你想断言它被调用一次时,你可以使用->atLeast()->times(1)(一次或多次) 或->times(1)(exactly one time)

于 2013-12-11T22:21:17.807 回答
4

要完成Wounter 的回答,您必须致电Mockery::close()

此静态调用会清理当前测试使用的 Mockery 容器,并运行您期望所需的任何验证任务。

这个答案帮助我理解了这个概念。

于 2016-02-16T16:54:09.753 回答
1

您不应该覆盖 , 的构造函数PHPUnit_Framework_TestCase用于setUp初始化目的。另请参阅我对#15051271#17504870的回答

于 2013-12-11T22:34:39.797 回答