0

我通过模拟控制器期望的存储库来对我的 Laravel 4 控制器进行单元测试。问题在于“商店”功能。当我对给定的控制器进行 POST 时,这是 Laravel 调用的函数。该函数被调用,但它应该itemData作为输入,但我不知道如何提供。这是我尝试过的:

ItemEntryController

class ItemEntryController extends BaseController
{
    protected $itemRepo;

    public function __construct(ItemEntryRepositoryInterface $itemRepo)
    {
        $this->itemRepo = $itemRepo;
    }

    public function store()
    {
        if(Input::has('itemData'))
        {
            $data = Input::get('itemData');

            return $this->itemRepo->createAndSave($data);
        }
    }
}

测试班

<?php

use \Mockery as m;

class ItemEntryRouteAndControllerTest extends TestCase {

protected $testItemToStore = '{"test":12345}';

public function setUp()
{
    parent::setUp();
    $this->mock = $this->mock('Storage\ItemEntry\ItemEntryRepositoryInterface');
}

public function mock($class)
{
    $mock = m::mock($class);
    $this->app->instance($class, $mock);

    return $mock;
}

public function testItemStore()
{
    Input::replace($input = ['itemData' => $this->testItemToStore]);

    $this->mock
        ->shouldReceive('createAndSave')
        ->once()
        ->with($input);

    $this->call('POST', 'api/v1/tools/itementry/items');
}
4

1 回答 1

2

好吧,你有几个选择。

集成测试

您可能想要遵循单元测试文档,它实际上有一个call()方法可以让您设置所有这些。这将引导应用程序并将使用您的数据库等。

这更像是一个集成测试而不是单元测试,因为它使用您的实际类实现。

这实际上可能更可取,因为单元测试控制器实际上可能没有多大意义(理论上它并没有做太多,但会调用其他已经单元测试的类)。但这涉及到单元测试、集成测试、验收测试以及适用于其中的所有细微差别。(阅读!)

单元测试

如果您实际上正在寻找单元测试,那么您需要使您的控制器可单元测试(哈!)。这(可能)意味着注入所有依赖项:

class ItemEntryController extends BaseController
{
    protected $itemRepo;

    // Not pictured here is actually making sure an instance of
    // Request is passed to this controller (via Service Provider or
    // IoC binding)
    public function __construct(ItemEntryRepositoryInterface $itemRepo, Request $input)
    {
        $this->itemRepo = $itemRepo;
        $this->request = $input;
    }

    public function store()
    {
        if($this->input->has('itemData'))
        {
            // Get() is actually a static method so we use
            // the Request's way of getting the $_GET/$_POST variables
            // see note below!
            $data = $this->input->input('itemData');

            return $this->itemRepo->createAndSave($data);
        }
    }
}

旁注:Input外观实际上是 Request 对象的一个​​实例,带有一个额外的静态方法get()

所以现在我们不再使用 Input,并且正在注入 Request 对象,我们可以通过模拟 Request 对象来对这个类进行单元测试。

希望有帮助!

于 2013-08-14T21:36:15.460 回答