繁体   English   中英

使用存储库的PHPUnit Laravel测试控制器

[英]PHPUnit Laravel Testing Controller that uses a Repository

我读了很多例子,看不到我在做什么错,请有人帮忙。

运行测试时出现错误(帖子底部出现错误),在浏览器中查看页面时不会发生。 我认为这是因为未正确实例化存储库,因此未触发相关方法? 或模拟中的API调用出现问题。

控制器:

namespace ShopApp\Http\Controllers\StoreFront;

use Illuminate\Http\Request;
use ShopApp\Http\Requests;
use ShopApp\Http\Controllers\Controller;
use ShopApp\Repositories\Contracts\CategoryRepositoryContract;
use ShopApp\Repositories\Contracts\PublicationRepositoryContract;

class PagesController extends Controller
{

    private $publication;
    private $category;


    public function __construct(PublicationRepositoryContract $publication, CategoryRepositoryContract $category){

    $this->publication = $publication;
    $this->category = $category;

    }

    /**
     * Homepage.
     * @return view
     * @internal param PublicationRepositoryContract $publication
     * @internal param CategoryRepositoryContract $category
     */
    public function home()
    {
        $mostRecent = $this->publication->getRecent();

        return view('pages/home')->with(compact('mostRecent'));

    }


}

出版物资料库:

<?php

namespace ShopApp\Repositories;

use ShopApp\Models\API\APIModel;
use GuzzleHttp\Client as GuzzleClient;
use Illuminate\Support\Facades\Config;
use ShopApp\Repositories\Contracts\PublicationRepositoryContract;

class localPublicationRepository extends APIModel implements PublicationRepositoryContract
{


    private $end_point; // where are we talking to?
    public $response; //what did we get back?

    public function __construct(GuzzleClient $client){

        parent::__construct(new $client(['base_uri' => Config::get('customerprovider.local.api.base_uri'), 'http_errors' => true]));

        $this->end_point = 'Publications';

    }


    /**
     * Get all publications
     */
    public function getAll(){

        $this->response = $this->get($this->end_point);

        $publications_with_slugs = $this->assembleSlugs($this->response);

        return $publications_with_slugs;

    }


    /**
     * Get recent publications
     */
    public function getRecent(){

        return $this->getAll();  //@todo - update this to just get the most recent

    }


}

测试:

<?php

namespace Tests\Unit\Controllers;

use Tests\TestCase;
use Mockery as m;

class PagesControllerTest extends TestCase
{

    public $publicationRepositoryContract;

    /**
     * Setup mocks etc
     */
    public function setUp()
    {

        parent::setup();

        $this->publicationRepositoryContract = m::mock('ShopApp\Repositories\Contracts\PublicationRepositoryContract');

    }


    /**
     * Teardown mocks
     */
    public function tearDown()
    {
        m::close();
        parent::tearDown();
    }


    /**
     * A basic test example.
     *
     * @return void
     */
    public function testHomepage()
    {


        $this->publicationRepositoryContract
            ->shouldReceive('getRecent')
            ->once();

        $this->app->instance('ShopApp\Repositories\Contracts\PublicationRepositoryContract', $this->publicationRepositoryContract);

        $response = $this->call('GET', '/');

        $response->assertStatus(200);

        // getData() returns all vars attached to the response.
        $mostRecent = $response->original->getData()['mostRecent'];

        $response->assertViewHas('mostRecent');

        $this->assertInstanceOf('Array', $mostRecent);


    }


}

测试错误:

Expected status code 200 but received 500.
Failed asserting that false is true.
 /home/vagrant/Code/imsnews-site/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:61
 /home/vagrant/Code/imsnews-site/tests/Unit/Controllers/PagesControllerTest.php:53

响应的内容($ response-> Content()):

<span class="exception_title"><abbr title="ErrorException">ErrorException</abbr> in <a title="/home/vagrant/Code/imsnews-site/storage/framework/views/229655ca372490c9c0b1f5e7e2d4e91e6d3bbf6c.php line 262">229655ca372490c9c0b1f5e7e2d4e91e6d3bbf6c.php line 262</a>:</span>\n
                            <span class="exception_message">Invalid argument supplied for foreach() (View: /home/vagrant/Code/imsnews-site/resources/views/pages/home.blade.php)</span>\n

来自home.blade.php的262行:

@foreach ($mostRecent as $key => $publication)

似乎很清楚,方法-> getRecent()进而在出版物存储库上调用-> getAll()并没有按原样返回数组,但是我不知道为什么。

刀片服务器没有抱怨变量mostRecent不存在,而是抱怨它在foreach中是无效的。

这与Guzzle以及它从模拟的测试对象中调用我的API有关吗?

请帮助,已经失去了数小时。

谢谢。

尝试模拟具体的存储库,然后将其替换为容器中的合同。 看来您在嘲笑合同,然后将其换成容器中的同一合同。

TL; DR:

关键是您必须具有-> andReturn([]); 在测试中,就像这样:

$this->publicationRepositoryContract
            ->shouldReceive('getRecent')
            ->once()->andReturn([]);

我的测试只有:

$this->publicationRepositoryContract
                ->shouldReceive('getRecent')
                ->once();

感谢Ayo指出这一点。 删除测试的其他部分后,情况才变得清楚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM