使用 phpunit DB::table()->get() 测试 Laravel 4.2 返回数组而不是对象

Posted

技术标签:

【中文标题】使用 phpunit DB::table()->get() 测试 Laravel 4.2 返回数组而不是对象【英文标题】:Testing Laravel 4.2 with phpunit DB::table()->get() returns arrays not an objects 【发布时间】:2015-09-12 20:44:51 【问题描述】:

我开始使用 phpunit 向旧版 Laravel 4.2 webapp 添加单元/功能测试,当使用 DB::table 时我看到一个奇怪的错误。

这是一个非常简单的例子,测试命中了一个控制器方法,该方法调用DB::table 然后死掉并转储结果。

class ExternalFormTest extends TestCase 

    public function testGetExternalFormThankYouPage()
    
        $response = $this->call('GET', 'test');

这是被命中的控制器方法。

public function getIndex()

    $results = DB::table('users')->get();
    dd($results);

这将返回一个数组数组。

..array(12) 
  [0] =>
  array(74) 
    'id' =>
    int(1)
    [0] =>
    int(1)
    'account_number' =>
    int(1000)
    [1] =>
    int(1000)
    'account_admin' =>
    int(1)

但如果我用浏览器点击它。

我得到一个对象数组...

array (size=12)
  0 => 
    object(stdClass)[1967]
      public 'id' => int 1
      public 'account_number' => int 1000
      public 'account_admin' => int 1
      public 'user_type' => int 1

这会导致整个应用程序出现大量错误。因为代码期望访问属性(即$individual_result->id)但结果是数组。我已经在内存和普通 mysql 数据库中使用 sqlite 进行了尝试。这是一个错误还是我错过了有关 Laravel 如何返回结果和/或 phpunit 如何工作的内容。

任何建议都会有所帮助。

这是我的 phpunit.xml 文件。

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
     backupStaticAttributes="false"
     bootstrap="bootstrap/autoload.php"
     colors="true"
     convertErrorsToExceptions="true"
     convertNoticesToExceptions="true"
     convertWarningsToExceptions="true"
     processIsolation="false"
     stopOnFailure="false"
     syntaxCheck="false"
>
    <testsuites>
        <testsuite name="Application Test Suite">
            <directory>./app/tests/</directory>
        </testsuite>
    </testsuites>
</phpunit>

【问题讨论】:

【参考方案1】:

获取模式由 config/database.php 中的 'fetch' 键配置。这应该是PDO::FETCH_CLASS。也许您将其设置为 PDO::FETCH_ASSOC 用于测试环境?作为一种解决方法,您可以尝试直接在控制器中设置它,看看是否可以解决它:

public function getIndex()

    DB::connection()->setFetchMode(PDO::FETCH_CLASS);
    $results = DB::table('users')->get();
    dd($results);

如果可行,那么只需弄清楚将其设置为FETCH_ASSOC 的位置即可。

【讨论】:

这行得通。搜索项目时,PDO::FETCH_ASSOC 或 PDO::FETCH_CLASS 出现的唯一位置是在 vendor\doctrine、vendor\laravel 和 vendor\symfony 下...所以我认为这不是本地设置问题。非常感谢您的帮助。【参考方案2】:

无论您是在 phpunit 上还是在控制器内部使用都无关紧要。行为(假定)是相同的。

您是否也在(我想)您的控制器上使用 ->get() 方法在浏览器上显示结果?

据我对 laravel 的了解,->get() 确实应该将结果作为数组返回。

【讨论】:

据我所知 ->get() 在典型使用中返回一个对象数组。我无法弄清楚为什么它在测试期间没有。来自文档“与原始查询一样,get 方法返回一个结果数组,其中每个结果都是 PHP StdClass 对象的一个​​实例。您可以通过将列作为对象的属性访问来访问每个列的值:”

以上是关于使用 phpunit DB::table()->get() 测试 Laravel 4.2 返回数组而不是对象的主要内容,如果未能解决你的问题,请参考以下文章

phpunit,在yii1中使用其他fixture

PHPUnit - getallheaders 不起作用

PHPUnit 在预期异常后不继续测试

DB::table('table') 和 model::('table') 的区别

PHPUnit Mock稍后改变期望

Symfony3.4:PHPUnit并且没有可用的代码覆盖驱动程序[关闭]