Mockery 在 Mocking Redis 连接时抛出错误:Mockery\Exception\BadMethodCallException

问题描述 投票:0回答:1

我有一个命令,里面运行着一些与Redis连接相关的方法。我想测试其中一些方法,为此我想模拟 Redis 连接。我是这样处理的:

protected function mockRedis(): void
{
    $redisConnection = Mockery::mock(Connection::class);
    app()->instance(Connection::class, $redisConnection);

    Redis::shouldReceive('connection')
        ->once()
        ->andReturn($redisConnection);

    Redis::connection()
        ->shouldReceive('client')
        ->once()
        ->andReturnSelf();

    Redis::connection()
        ->client()
        ->shouldReceive('ping')
        ->once()
        ->andReturn(true);

    Redis::connection()
        ->client()
        ->shouldReceive('close')
        ->once();

    Redis::shouldReceive('subscribe')
        ->once()
        ->with(['socket-data'], Mockery::type('callable'))
        ->andReturnUsing(function ($channels, $callback) {
            $message1 = json_encode([
                'type' => 'alive',
                'interval' => 10,
                'time' => '2023-10-04T10:00:00+00:00',
            ]);

            $message2 = json_encode([
                'type' => 'some_type',
                'data' => 'some_data',
            ]);

            $callback($message1);
            $callback($message2);
        });
}

我要测试的线路如下:

// some openswoole methods...
// ...
Redis::connection()->client()->ping();

// ...
Redis::connection()->client()->close();

// ...
Redis::subscribe(['socket-data'], function (string $message) {
    //...
});

发现错误:

1) Tests\Feature\RedisSubscribeTest::test_redis_subscribe_command
Mockery\Exception\BadMethodCallException: Received Mockery_0_Illuminate_Redis_Connections_Connection::client(), but no expectations were specified

有什么想法吗?

php laravel redis mockery laravel-testing
1个回答
0
投票

您应该使用

andReturnSelf()
设置链式调用的期望,并为后续链式方法返回一个新的模拟。

protected function mockRedis(): void
{
    $redisConnection = Mockery::mock(Connection::class);
    app()->instance(Connection::class, $redisConnection);

    // Set up the initial Redis::connection() expectation.
    Redis::shouldReceive('connection')
        ->once()
        ->andReturn($redisConnection);

    // Set up the chained method calls.
    $redisConnection->shouldReceive('client')
        ->once()
        ->andReturnSelf();

    $clientMock = Mockery::mock(); // Create a mock for the client.

    // Expect the ping method on the client mock.
    $clientMock->shouldReceive('ping')
        ->once()
        ->andReturn(true);

    // Expect the close method on the client mock.
    $clientMock->shouldReceive('close')
        ->once();

    // Set up the chained method calls.
    $redisConnection->shouldReceive('client')
        ->once()
        ->andReturn($clientMock);

    // Set up the Redis::subscribe expectation.
    Redis::shouldReceive('subscribe')
        ->once()
        ->with(['socket-data'], Mockery::type('callable'))
        ->andReturnUsing(function ($channels, $callback) {
            $message1 = json_encode([
                'type' => 'alive',
                'interval' => 10,
                'time' => '2023-10-04T10:00:00+00:00',
            ]);

            $message2 = json_encode([
                'type' => 'some_type',
                'data' => 'some_data',
            ]);

            $callback($message1);
            $callback($message2);
        });
}
© www.soinside.com 2019 - 2024. All rights reserved.