Laravel / PHPUnit:运行测试时没有模拟类

Posted

技术标签:

【中文标题】Laravel / PHPUnit:运行测试时没有模拟类【英文标题】:Laravel/PHPUnit: Class not being mocked when tests are run 【发布时间】:2019-02-13 19:28:38 【问题描述】:

我正在测试一个调用自定义服务的类并想模拟自定义服务。

错误是:

App\Jobs\CustomApiTest::getrandomInfo
Error: Call to a member function toArray() on null

这是因为在getrandomInfo() 中有一个获取 ID 的数据库调用,并且由于没有条目,测试数据库当前返回 null,但是测试甚至不应该走那么远,因为我正在模拟 @987654323 @函数。

机器配置:

Laravel 5.2

phpUnit 4.8

我无法更新我的配置。

MainClass.php

namespace App\Jobs;
use App\Services\CustomApi;

class MainClass

    public function handle()
    
        try 
            $date = Carbon::yesterday();
            $data = (new CustomApi($date))->getData();
         catch (Exception $e) 
            Log::error("Error, $e->getMessage()");
        
    

MainClassTest.php

nameSpace App\Jobs;
use App\Services\CustomApi;
class MainClassTest extends \TestCase

    /** @test */
    public function handleGetsData()
    
    $data = json_encode([
            'randomInfo' => '',
            'moreInfo' => ''
        ]);
    $customApiMock = $this->getMockBuilder(App\Services\CustomApi::class)
            ->disableOriginalConstructor()
            ->setMethods(['getData'])
            ->getMock('CustomApi', ['getData']);
        $customApiMock->expects($this->once())
            ->method('getData')
            ->will($this->returnValue($data));

        $this->app->instance(App\Services\CustomApi::class, $customApiMock);

    (new MainClass())->handle();
    

CustomApi 片段

namespace App\Services;
class CustomApi

    /**
     * @var Carbon
     */
    private $date;

    public function __construct(Carbon $date)
    
        $this->date = $date;
    

    public function getData() : string
    
        return json_encode([
            'randomInfo' => $this->getrandomInfo(),
            'moreInfo' => $this->getmoreInfo()
        ]);
    

我尝试了上述代码的许多变体,包括:

Not using `disableOriginalConstructor()` when creating $externalApiMock.
Not providing parameters to `getMock()` when creating $externalApiMock.
Using `bind(App\Services\CustomApi::class, $customApiMock)` instead of instance(App\Services\CustomApi::class, $customApiMock) for the app.
Using willReturn($data)`` instead `will($this->returnValue($data))`.

【问题讨论】:

你能更新到最新的 Laravel 吗?并发布您的错误? @Bart,我无法更新到最新的 Laravel,因为更新需要对代码库进行许多调整,并且需要分段完成,但开发仍需要继续进行。我已经用收到的错误更新了问题。 我还是建议更新,如果你不能更新,那么你的代码可能有问题,或者你的 IDE 无法更改所需的东西...... 【参考方案1】:

我最终创建了一个服务提供者并将其注册到 app.php 文件中。看起来应用程序没有将实例保存在容器中,而是在绑定到服务时工作。

【讨论】:

以上是关于Laravel / PHPUnit:运行测试时没有模拟类的主要内容,如果未能解决你的问题,请参考以下文章

Laravel PHPUnit 测试运行产生异常 调度器创建后无法设置默认工厂

在 Laravel 8 中运行多个 PHPUnit 测试时出错

Laravel PHPUnit测试运行产生异常创建调度程序后无法设置默认工厂

PHPUnit 似乎没有运行 Laravel 迁移

在没有 /vendor/bin/ 的 laravel 4 中使用 phpunit

为啥 Laravel 中的 PHPUnit 不能访问存在的路由?