Laravel Mockery phpunit 错误:无法解析的依赖项解析

Laravel Mockery phpunit error: Unresolvable dependency resolving

提问人:Martijn Bastiaansen 提问时间:11/1/2023 更新时间:11/1/2023 访问量:32

问:

测试相当新,但不能用门面进行测试才能正常工作。代码本身工作正常。只是希望测试也能正常工作:')

服务提供商:

<?php

class ServiceProvider extends AbstractServiceProvider implements DeferrableProvider
{
    public function register(): void
    {
        $this->app->singleton(RedisHashManager::class, $this->hashManagerSingleton(...));
    }

    /**
     * @return array<int, string>
     */
    public function provides(): array
    {
        return [RedisHashManager::class];
    }

    private function hashManagerSingleton(Application $app): RedisHashManager
    {
        return new RedisHashManager($app->make(Factory::class), 'cache');
    }
}

立面

<?php

class RedisHashCache extends Facade
{
    protected static function getFacadeAccessor(): string
    {
        return RedisHashManager::class;
    }
}

要测试的代码:

<?php

trait HashTrait
{
    protected function getHashes(array $keys, array $fields): Collection
    {
        $keys = collect($keys)->mapWithKeys(static function ($key) use ($fields) {
            return [$key => $fields];
        })->toArray();

        $fieldCount = count($fields);

        return RedisHashCache::getHashes($keys)
            ->reject(static function ($data) use ($fieldCount) {
                return count($data) !== $fieldCount;
            });
    }
}

测试本身:

<?php

class HashTraitTest extends TestCase
{
    use HashTrait;

    public function testGetHashes(): void
    {
        RedisHashCache::shouldReceive('getHashes')
            ->once();

        $this->getHashes(['canidae:canis:lupus:lycaon'], ['color', 'food']);
    }
}

(我删除了命名空间和用途,它们在真实代码中)

当我运行测试时,我收到以下错误:Illuminate\Contracts\Container\BindingResolutionException: Unresolvable dependency resolving [Parameter #1 [ <required> string $connectionName ]] in class AbstractRedisManager

AbstractRedisManager 由 RedisHashManager 扩展,在构造中需要 2 个参数:一个 RedisFactory 作为第一个正确解析的参数,以及一个给出错误的简单字符串。

第二个参数没有默认值,当我设置默认值时,它工作正常。但我不知道这是否是我针对该问题提供的正确/唯一解决方案。

希望有人能帮助我?

php laravel 依赖注入 phpunit laravel-façade

评论

0赞 matiaslauriti 11/2/2023
首先,在我 15 年的 PHP 经验中,我从未见过匿名静态函数,这是第一次,你为什么要使用它们(我现在很好奇)?其次,我现在不完全记得 Facade 是如何工作的,但我认为它在被模拟时跳过了在服务提供者上找到的定义,因为这实际上是 Mocking 正在做的事情,它试图运行被模拟的类的构造函数(在这种情况下,你在被模拟时不会从定义中获得实例)。singleton
0赞 Martijn Bastiaansen 11/2/2023
匿名静态函数是某种微优化。该类未绑定到函数。我确实发现它没有从单例中获取实例。但这就提出了一个问题,它如何知道为立面获得正确的类。有点神奇。
0赞 matiaslauriti 11/2/2023
如果确实存在并且正在扩展一个类,那么它将被找到。Differnet 可能是,如果您在单例上定义了一个别名而不是类,例如,在您的外观中,您正在返回 ,那么它将找不到,并且它实际上需要运行单例定义才能返回某些东西,也许这对您有用RedisHashManager'redisHash'redisHash

答: 暂无答案