照亮Http响应-属性"original"包含字符串而不是视图对象


IlluminateHttpResponse - Attribute "original" contains string instead of View object

我从控制器的方法返回一个视图,如下所示:

return view('Main::pages.content-page', compact('content'));

视图正确呈现,然而,当我添加响应对象时,我看到响应对象的属性"original"是一个字符串,而它应该是视图对象。

Response {#385 ▼
    +original: """
    <!DOCTYPE html>'n
    <html lang="en">'n
        <head>'n
        <meta charset="utf-8">'n
        <meta http-equiv="X-UA-Compatible" content="IE=edge">'n
        <meta name="viewport" content="width=device-width, initial-scale=1">'n
        <meta name="author" content="">'n
        <meta name="csrf-token" content="2CQirHnZ7isCBRfkhOYkzPAWOzNIqJISrbb1mfDv">'n
        <meta name="description" content="">'n
        <meta name="keywords" content="">'n
          <title id="page_title">    D&eacute;couvrir'n </title>'n
        .........

这是预期的行为,因为我的测试实际上因为它而失败,因为在我的测试中,我基本上是在做

$this->get(route('main.page', ['content' => $content->slug]))
     ->assertResponseOk()
     ->assertViewHas('content', $content);

我得到以下失败

F                                                                   1 / 1 (100%)
Time: 179 ms, Memory: 20.00MB
There was 1 failure:
1) IndexControllerTest::testGetPageMethod
The response was not a view.
Failed asserting that false is true.

查看assertViewHas()方法的结构,我们可以看到为什么

/**
 * Assert that the response view has a given piece of bound data.
 *
 * @param  string|array  $key
 * @param  mixed  $value
 * @return $this
 */
public function assertViewHas($key, $value = null)
{
    if (is_array($key)) {
        return $this->assertViewHasAll($key);
    }
    if (! isset($this->response->original) || ! $this->response->original instanceof View) {
        return PHPUnit::assertTrue(false, 'The response was not a view.');
    }
    ......

条件! $this->response->original instanceof View失败,因为original是一个字符串,但应该是一个视图对象。

所以我在这里迷路了。如果是这样,为什么assertViewHas方法中的条件是预期行为?

I am on Laravel Homestead version '3.0.2'
Laravel 5.2.45

我遇到了同样的问题。在我的例子中,事实证明响应在准备时正在接收一个View对象,但是在返回响应之前触摸响应的"after"中间件类之一正在将View对象转换为字符串。

您是否偶然使用了genealabs/laravel-caffeine包?正是中间件导致了我的问题。通过将该包设置为不在测试环境中注册,我能够解决这个问题。

我遇到了同样的问题。当我从Blade模板中删除@if/@endif -子句时,我可以将响应返回为View

与Ryan Durham的回答相似,问题是一个中间件包对我来说也是。

试着想想你可能正在运行什么中间件,最有可能是由依赖注入的。在我的例子中是beyondcode/laravel-query-detector。找到有问题的中间件可能需要进行一些搜索和试错。如果有一种简单的方法来找到所有活动的中间件"在传输",我很想知道!

解决方案是找到有问题的中间件类,并将以下内容添加到TestCase类的setUp方法中,使其看起来像这样:
protected function setUp(): void
{
    parent::setUp();
    $this->withoutMiddleware([OffendingMiddleware::class]);
    // …
}

这可以防止中间件被加载到任何扩展TestCase类的测试用例中,这应该是它们的全部。

这个答案仍然适用于Laravel 9。