【问题标题】:Laravel resource controller testing gives NotFoundHttpException the second timeLaravel 资源控制器测试第二次给出 NotFoundHttpException
【发布时间】:2015-02-24 12:48:42
【问题描述】:

我在使用 Laravel 4 进行测试时遇到了一件非常奇怪的事情。它看起来像一个错误,但可能有一个合乎逻辑的解释。

我在干净的 Laravel 安装中复制了“错误”,这是我的代码:

我的资源控制器/app/controllers/TestController.php

(使用php artisan controller:make TestController 创建)

class TestController extends \BaseController {

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        return Response::json(array());
    }

    // The end of the file is unchanged

在我的app/routes.php:

Route::get('/', function()
{
    return View::make('hello');
});

// Note the composed part of the URL.
// My problem isn't present if I just use `myapi` or `path` as a url
Route::resource('myapi/path', 'TestController');

添加于/app/test/ExampleTest.php:

public function testTest()
{
    $res = $this->call('GET', 'myapi/path');

    // Until here everything works right
    $this->assertEquals(json_decode($res->getContent()), array());

    // Now I call the same URL a second time
    $res = $this->call('GET', 'myapi/path');

    $this->assertEquals(json_decode($res->getContent()), array());
}

现在我运行 phpunit,得到的结果如下:

There was 1 error:

1) ExampleTest::testTest
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: 

/home/me/Web/laraveltest/bootstrap/compiled.php:5531
/home/me/Web/laraveltest/bootstrap/compiled.php:4848
/home/me/Web/laraveltest/bootstrap/compiled.php:4836
/home/me/Web/laraveltest/bootstrap/compiled.php:4828
/home/me/Web/laraveltest/bootstrap/compiled.php:721
/home/me/Web/laraveltest/bootstrap/compiled.php:702
/home/me/Web/laraveltest/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/laraveltest/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:332
/home/me/Web/laraveltest/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/laraveltest/app/tests/ExampleTest.php:25

在我的另一个项目中,我得到了一个稍微不同的回溯,但我的印象是同样的问题:(但我不知道为什么另一个被编译而这个没有)

2) UnitModelTest::testOther
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: 

/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:148
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1049
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1017
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:996
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:775
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:745
/home/me/Web/my-project/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/my-project/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:327
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/my-project/app/tests/UnitModelTest.php:32

在这两种情况下,测试文件的跟踪中给出的行对应于测试的 second call

正如我在 routes.php 文件的 cmets 中所指出的,如果我使用没有斜杠的简单 url,则测试通过没有问题。

从浏览器使用api没有问题。

我在 StackOverflow 上找到了许多与 NotFoundHttpException 相关的主题,但没有一个看起来像我的。这个是在测试时特别出现的,并且只会在第二次调用时触发错误。

那么我在这里做错了什么?或者它真的是一个错误?

【问题讨论】:

  • 如果你有不同的测试函数并且在每个函数中只调用一次怎么办?
  • @lukasgeiter 是的,如果我像你说的那样,那没问题。但是我有一个测试,我查询控制器,然后做一些事情,然后重新查询它以查看值是否正确更改(例如列表中是否有 2 个新项目?)
  • 我真的不知道您的问题的原因,但作为解决方法,您也许可以使用两个测试,depend 对彼此
  • 这会有点奇怪,因为第一个测试不包含断言。我也可以将第一部分放在setUp() 函数中,然后将变量存储为类成员。我会等着看会不会有更好的事情发生。否则我就那样做。
  • 我们您至少可以断言呼叫是否正常工作(200 响应或您返回的其他内容)

标签: php exception laravel laravel-4 phpunit


【解决方案1】:

问题是calls用同一个客户端做的会相对使用提供的URI。这意味着您实际调用的是:

  1. myapi/路径
  2. myapi/myapi/路径

如果您在 URL 前添加带有 / 的前言,则可以解决此问题,以使它们绝对位于应用程序的根目录。

public function testTest()
{
    $res = $this->call('GET', '/myapi/path');

    // Until here everything works right
    $this->assertEquals(json_decode($res->getContent()), array());

    // Now I call the same URL a second time
    $res = $this->call('GET', '/myapi/path');

    $this->assertEquals(json_decode($res->getContent()), array());
}


如果您遇到类似的其他问题,拨打电话通常会有所帮助

$this->refreshApplication();

(这也会创建一个新的client,因此也解决了这个问题)

【讨论】:

  • 成功了!我从来没有读过提到它的东西。甚至文档也没有在 url 的开头使用斜杠。
  • 不,不幸的是它没有。而且这不是很明显,因为框架中的任何地方都不需要它们(例如在路由声明中)
  • 谢谢!我遇到了这个问题,不知道出了什么问题。
【解决方案2】:

在我的情况下,发生此错误是因为我将 public 目录名称更改为 public_html 我的解决方案是将此放在 \App\Providers\AppServiceProvider register 方法中。

public function register()
{
    // ...

    $this->app->bind('path.public', function() {
        return base_path('public_html');
    });
}

【讨论】:

    猜你喜欢
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 2014-10-10
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多