Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 拉维公司;mockry:在不影响数据库的情况下对更新方法进行单元测试_Php_Unit Testing_Laravel_Laravel 4_Mockery - Fatal编程技术网

Php 拉维公司;mockry:在不影响数据库的情况下对更新方法进行单元测试

Php 拉维公司;mockry:在不影响数据库的情况下对更新方法进行单元测试,php,unit-testing,laravel,laravel-4,mockery,Php,Unit Testing,Laravel,Laravel 4,Mockery,好吧,我对单元测试、mocky和laravel都是新手。我试图对我的资源控制器进行单元测试,但我被更新功能卡住了。不确定我是做错了什么,还是只是想错了 这是我的控制器: class BooksController extends \BaseController { // Change template. protected $books; public function __construct(Book $books) { $this->

好吧,我对单元测试、mocky和laravel都是新手。我试图对我的资源控制器进行单元测试,但我被更新功能卡住了。不确定我是做错了什么,还是只是想错了

这是我的控制器:

class BooksController extends \BaseController {

    // Change template.
    protected $books;

    public function __construct(Book $books)
    {
        $this->books = $books;
    }

    /**
     * Store a newly created book in storage.
     *
     * @return Response
     */
    public function store()
    {
        $data       = Input::except(array('_token'));
        $validator  = Validator::make($data, Book::$rules);

        if($validator->fails())
        {
            return Redirect::route('books.create')
                ->withErrors($validator->errors())
                ->withInput();
        }

        $this->books->create($data);

        return Redirect::route('books.index');
    }

    /**
     * Update the specified book in storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function update($id)
    {
        $book       = $this->books->findOrFail($id);
        $data       = Input::except(array('_token', '_method'));
        $validator = Validator::make($data, Book::$rules);

        if($validator->fails())
        {
            // Change template.
            return Redirect::route('books.edit', $id)->withErrors($validator->errors())->withInput();
        }

        $book->update($data);

        return Redirect::route('books.show', $id);
    }
}
以下是我的测试:

public function testStore()
{
    // Add title to Input to pass validation.
    Input::replace(array('title' => 'asd', 'content' => ''));

    // Use the mock object to avoid database hitting.
    $this->mock
        ->shouldReceive('create')
        ->once()
        ->andReturn('truthy');

    // Pass along input to the store function.
    $this->action('POST', 'books.store', null, Input::all());

    $this->assertRedirectedTo('books');
}

public function testUpdate()
{
    Input::replace(array('title' => 'Test', 'content' => 'new content'));

    $this->mock->shouldReceive('findOrFail')->once()->andReturn(new Book());
    $this->mock->shouldReceive('update')->once()->andReturn('truthy');

    $this->action('PUT', 'books.update', 1, Input::all());      

    $this->assertRedirectedTo('books/1');
}
问题是,当我这样做时,我从mockry\u 0\u Book中得到了
mockry\Exception\InvalidCountException:Method update(),应该精确调用1次,但调用0次。
因为我的控制器中有
$Book->update($data)
。如果我将其更改为
$this->books->update($data)
,它将被正确地模拟,并且不会触动数据库,但当从前端使用该函数时,它将更新我的所有记录

我想我只是想知道如何正确地模拟
$book对象


我够清楚了吗?否则请告诉我。谢谢

尝试模拟
findOrFail
方法,不返回
新书
,而是返回一个包含更新方法的模拟对象

$mockBook = Mockery::mock('Book[update]');
$mockBook->shouldReceive('update')->once();
$this->mock->shouldReceive('findOrFail')->once()->andReturn($mockBook);

起初我以为你的
$this->book
是一本很好的书,但仔细看,它看起来更像是一个雄辩的模型。对吗?对。我曾考虑过使用存储库,但我认为这会给我带来太多的困惑。问题是,这是人们使用存储库的主要原因之一:它使测试变得更加容易。但必须有一种方法来模拟单个$book对象,对吗?为了对整个控制器进行单元测试,我真的被迫使用存储库模式吗?好先生,你是救命恩人。这对我来说很有意思,甚至很有意义。谢谢np,很高兴我能帮忙:)