使用 Laravel 和 PHPUnit 模拟函数

Posted

技术标签:

【中文标题】使用 Laravel 和 PHPUnit 模拟函数【英文标题】:Mocking a function using Laravel and PHPUnit 【发布时间】:2015-07-10 14:30:57 【问题描述】:

我在一些项目中使用 Laravel,我正在尝试为一个函数创建一个测试。这是我的控制器中的功能:

 public function showThoseThings()
  
    return parent::httpRequest(
        function ($context) 
            $context->results['item'] = $this->object->findOrFail(list_id)->getElements;
        
    );
  

“getElements()”函数在模型中定义如下:

public function getElements()
    
        return $this->belongsToMany(
            'things',
            'thing_to_list',
            'list_id',
            'thing_id'
        )
                ->withPivot('position')
                ->orderBy('thing_to_list.position');
    

基本上在后端有三个表,一个列表表是事物的集合,然后是一个事物表,其中包含与列表关联的多个事物,然后我们有数据透视表。我怎么能用 Laravel 模拟这个。这是我一直在做的事情:

public function testShowThoseTHingsSuccess()

    $this->mock->shouldReceive('findOrFail')->with(1)->andReturn($this->mock);
    $this->mock->shouldReceive('getElements')->once()->andReturn($this->mock);

   $response = $this->call('GET', 'workingURI');
    var_dump($response);
     $this->assertTrue($response->isOk());

但是在命令行中运行 phpunit 时,我得到了:

"Unknown Error","message":"SQLSTATE[HY000] [1045] Access denied for user... 无法断言 false 为真"。

【问题讨论】:

这可能会有所帮助:***.com/a/21688413/1903366 【参考方案1】:

我不知道您的 $this->mock->.. 方法在做什么,但显然不是在模拟您想要的模型。 因为错误表明某些东西试图访问数据库并且没有正确的凭据。

还有以下几行:

$this->mock->shouldReceive('findOrFail')->with(1)->andReturn($this->mock);
$this->mock->shouldReceive('getElements')->once()->andReturn($this->mock);

对我来说没有意义,你创建了一个模型的模拟,当方法 findOrFailgetElements 被触发时,你返回相同的对象。方法 getElements 告诉我应该返回一些带有模型的数组..

更多关于使用测试数据库的信息

当您使用 laravel 运行单元测试并使用基本测试类时,Laravel 会将 environment 设置为 testing。确保您为此环境设置了正确的数据库配置。

您可以使用 I.E.以下配置在内存中创建数据库进行测试:

// app/config/testing/database.php

<?php

return array(

    'default' => 'sqlite',

    'connections' => array(
        'sqlite' => array(
            'driver'   => 'sqlite',
            'database' => ':memory:',
            'prefix'   => ''
        ),
    )
);

不要忘记在测试之前迁移您的 DB 架构,将以下行放在基础测试类的 public function setUp() 中。

Artisan::call('migrate'); 

更多关于模拟数据库的信息:NetTuts testing laravel models

【讨论】:

啊哈,我在上面的评论中写道(现已删除)app/config/testing/database.php 应该是 config/testing/database.php,但是在阅读了更多内容后,我发现您的信息对于 Laravel 4 是正确的。Laravel 5 将配置文件夹从app/config/ 移动到config/,但据我所知,级联环境特定配置不再适用于 L5。但是,有第三方软件包可以让它工作。

以上是关于使用 Laravel 和 PHPUnit 模拟函数的主要内容,如果未能解决你的问题,请参考以下文章

在 PHPUnit 中调用路由时如何在 Laravel 8 中模拟 Eloquent 模型

PHPUnit 问题断言模拟是使用 Laravel 的 ReflectionProperty 对象

如何用 phpunit 模拟 Laravel Eloquent 模型?

如何在 PHPUnit / Laravel 中模拟 JSON 文件

用于 PHPunit 的 Laravel 5.4 模型模拟

PhpUnit - 用关系模拟 laravel 模型