我如何 运行 在 Redis pub/sub 上进行 phpunit 测试?
How do I run a phpunit test on Redis pub/sub?
我正在构建一个消息系统,其中 Redis 在 Laravel 端发布并在节点服务器上订阅。我想使用 PHPUnit 测试 redis pub 方法中存储的内容,但我不知道从哪里开始。
控制器
class MessageController extends Controller
{
public function store(Conversation $conversation, Request $request)
{
$user = Auth::user();
$message = Message::create([
'body' => $request->input('message'),
'conversation_id' => $conversation->id,
'sender_id' => $user->id,
'type' => 'user_message'
]);
$redis = Redis::connection();
$data = new MessageResource($message);
$redis->publish('message', $data);
}
}
当前测试
/** @test */
public function a_user_can_send_a_message()
{
$this->actingAs($user = User::factory()->create());
$message = Message::factory()->make(['sender_id' => $user->id]);
$conversation Conversation::factory()->create();
$response = $this->json('POST', '/api/message/'. $conversation->id, ['message' => $message->body])
->assertStatus(201);
$response->assertJsonStructure([
'data' => [
'body',
'sender',
]
]);
}
本质上,我想要查看的是消息是否已在 Redis 上发布。我不确定该怎么做,我认为您可能需要在之后清除来自 Redis 的消息,不是吗?
你的测试应该是这样的:
public function test_a_user_can_send_a_message()
{
$redisSpy = Redis::spy();
$redisSpy->shouldReceive('connection')->andReturnSelf();
$this->actingAs($user = User::factory()->create());
$message = Message::factory()->make(['sender_id' => $user->id]);
$conversation = Conversation::factory()->create();
$this->postJson("/api/message/{$conversation->id}", ['message' => $message->body]);
$this->assertDatabaseCount('messages', 1);
$redisSpy->shouldHaveReceived('publish')
->with('message', new MessageResource(Message::first()));
}
如您所见,我添加了 Redis::spy();
这将允许“监视”从 Redis
调用的内容。你仍然可以 mock 方法,我们必须这样做,因为你使用 Redis::connect();
然后 $redis->publish(...)
,所以我们将 return spy 当 connect
被调用时,这就是为什么我们做 shouldReceive('connection')->andReturnSelf()
.
在代码的末尾,我们检查 $redis->publish
是否使用参数 'message'
和包含所需消息的资源调用。两者都必须匹配才能通过此断言,否则您将看到一个模拟错误。
我正在构建一个消息系统,其中 Redis 在 Laravel 端发布并在节点服务器上订阅。我想使用 PHPUnit 测试 redis pub 方法中存储的内容,但我不知道从哪里开始。
控制器
class MessageController extends Controller
{
public function store(Conversation $conversation, Request $request)
{
$user = Auth::user();
$message = Message::create([
'body' => $request->input('message'),
'conversation_id' => $conversation->id,
'sender_id' => $user->id,
'type' => 'user_message'
]);
$redis = Redis::connection();
$data = new MessageResource($message);
$redis->publish('message', $data);
}
}
当前测试
/** @test */
public function a_user_can_send_a_message()
{
$this->actingAs($user = User::factory()->create());
$message = Message::factory()->make(['sender_id' => $user->id]);
$conversation Conversation::factory()->create();
$response = $this->json('POST', '/api/message/'. $conversation->id, ['message' => $message->body])
->assertStatus(201);
$response->assertJsonStructure([
'data' => [
'body',
'sender',
]
]);
}
本质上,我想要查看的是消息是否已在 Redis 上发布。我不确定该怎么做,我认为您可能需要在之后清除来自 Redis 的消息,不是吗?
你的测试应该是这样的:
public function test_a_user_can_send_a_message()
{
$redisSpy = Redis::spy();
$redisSpy->shouldReceive('connection')->andReturnSelf();
$this->actingAs($user = User::factory()->create());
$message = Message::factory()->make(['sender_id' => $user->id]);
$conversation = Conversation::factory()->create();
$this->postJson("/api/message/{$conversation->id}", ['message' => $message->body]);
$this->assertDatabaseCount('messages', 1);
$redisSpy->shouldHaveReceived('publish')
->with('message', new MessageResource(Message::first()));
}
如您所见,我添加了 Redis::spy();
这将允许“监视”从 Redis
调用的内容。你仍然可以 mock 方法,我们必须这样做,因为你使用 Redis::connect();
然后 $redis->publish(...)
,所以我们将 return spy 当 connect
被调用时,这就是为什么我们做 shouldReceive('connection')->andReturnSelf()
.
在代码的末尾,我们检查 $redis->publish
是否使用参数 'message'
和包含所需消息的资源调用。两者都必须匹配才能通过此断言,否则您将看到一个模拟错误。