如何测试 Laravel Scout 添加数据到索引,并确保搜索结果匹配正确?

huangapple go评论101阅读模式
英文:

How to test Laravel Scout adds data to indexes and search results match properly?

问题

我试图使用PestPHP来测试我的Laravel Scout(Mellisearch)。测试模型数据是否发送到了搜索索引并且搜索是正确的。

对于搜索,如果我搜索用户 $user = User::search('wanna_coder101')->get();,那么它会返回用户模型 toArray() 的结果。或者只是这个示例

使用PestPHP,结合 Event::fake(),我们可以测试广播是否会被分发。我想做同样的事情,但与搜索一起。

  1. it('测试广播是否被正确分发', function () {
  2. // 设置假事件
  3. Event::fake();
  4. // 分发广播
  5. MyBroadcast::dispatch(auth()->user());
  6. // 断言广播被正确分发
  7. Event::assertDispatched(MyBroadcast::class);
  8. });

在测试中,广播驱动程序会自动使用 null 或日志而不是 redis。

Scout 是否可以做同样的事情,使用集合来代替,因此可以在本地测试搜索索引是否被发送,并且可以获取数据以测试它是否是正确的响应。

是唯一的选择是使用这个Laravel Scout 测试包吗?

版本信息:

  1. "php": "^8.1.0",
  2. "laravel/framework": "^10.0",
  3. "laravel/scout": "^9.8",
  4. "pestphp/pest-plugin-laravel": "^1.4",
  5. "phpunit/phpunit": "^9.5.10"
英文:

I'm trying to test my Laravel Scout (Mellisearch) with PestPHP. Testing the model data gets sent to the search index and the search is correct.

For the search, if I were to search user $user = User::search('wanna_coder101')->get();, then it'd return the user model toArray() results. Or is that just this example?

Using PestPHP, with Event::fake(), we can test whether a broadcast would dispatch. I want to do the same thing but with the Search.

  1. it('Test Broadcast Dispatches', function () {
  2. // Setup fake event
  3. Event::fake();
  4. // Dispatch Broadcast
  5. MyBroadcast::dispatch(auth()->user());
  6. // Assert Broadcast Correctly Dispatched
  7. Event::assertDispatched(MyBroadcast::class);
  8. });

The broadcast driver, in test, would automatically use null or log during testing instead of redis.

Can scout do the same, use collection instead, hence can locally test search indexes get sent off and can get data back to test it's the correct response.

Is the only option to use this Laravel Scount testing package?

Versions

  1. "php": "^8.1.0",
  2. "laravel/framework": "^10.0",
  3. "laravel/scout": "^9.8",
  4. "pestphp/pest-plugin-laravel": "^1.4",
  5. "phpunit/phpunit": "^9.5.10",

答案1

得分: 0

在阅读了Scout包后,没有本地驱动程序,只有数据库和集合(使用数据库)。

使用此 laravel数组scout测试包。它添加了一个数组驱动程序和一堆测试方法。然后可以测试模型是否与搜索索引同步。

搜索索引是正确的数据格式,用于测试搜索返回预期结果。

  1. use App\Models\User;
  2. use App\Models\Quest;
  3. use Sti3bas\ScoutArray\Facades\Search;
  4. use function Pest\Laravel\{actingAs};
  5. use Illuminate\Foundation\Testing\RefreshDatabase;
  6. // 必要以访问Laravel测试助手和数据库工厂的内容
  7. uses(
  8. Tests\TestCase::class,
  9. RefreshDatabase::class
  10. )->group('search');
  11. // 为每个测试自动设置一个新的已认证用户
  12. beforeEach(function () {
  13. actingAs(User::factory()->create());
  14. });
  15. /**
  16. * 测试任务是否已同步到搜索索引
  17. */
  18. it('测试已创建的任务是否已同步到搜索索引', function () {
  19. // 获取当前已认证用户以关联任务
  20. $quest = Quest::factory()->create([
  21. 'user_id' => auth()->id()
  22. ]);
  23. // 确保任务已同步到搜索索引
  24. Search::assertSynced($quest);
  25. });
  26. /**
  27. * 测试搜索索引中的任务数据格式是否正确
  28. */
  29. it('测试已创建的任务是否存在于搜索索引中', function () {
  30. // 获取当前已认证用户以关联任务
  31. $quest = Quest::factory()->create([
  32. 'user_id' => auth()->id()
  33. ]);
  34. // 确保搜索索引中的任务数据格式正确
  35. Search::assertContains($quest)
  36. ->assertContains($quest, function ($record) use ($quest) {
  37. // 注意我只使用了一个子集来进行测试,而不是 $request = $quest->toArray()?
  38. // 这是因为搜索索引会添加一些额外的字段,而 $quest->toArray() 会去掉一些数据库添加的字段
  39. return [
  40. 'id' => $record['id'],
  41. 'name' => $record['name'],
  42. 'description' => $record['description'],
  43. 'user_id' => $record['user_id'],
  44. ] == [
  45. 'id' => $quest->id,
  46. 'name' => $quest->name,
  47. 'description' => $quest->description,
  48. 'user_id' => $quest->user_id,
  49. ];
  50. });
  51. });
  52. /**
  53. * 测试Quest模型的搜索功能
  54. */
  55. it('测试搜索Quest是否正确', function () {
  56. // 获取当前已认证用户以关联任务
  57. $quest = Quest::factory()->create([
  58. 'user_id' => auth()->id()
  59. ]);
  60. // 通过名称搜索刚刚创建的任务
  61. $questSearch = Quest::search($quest->name)->where('user_id', $quest->user_id)->get();
  62. // 确保我们只有一个结果
  63. expect($questSearch)
  64. ->toHaveCount(1);
  65. // 确保搜索结果与我们创建的任务匹配
  66. expect($questSearch->first()->toArray())
  67. ->toMatchArray($quest->toArray());
  68. });
英文:

After reading the Scout package, there's no local driver, only database and collection (which uses the database).

Use this laravel array scout testing package. Which adds an array driver and a bunch of test methods. Then it's possible to test the model is synced to the search index.

The search index is the correct data format and to test the search returns the expected results.

  1. use App\Models\User;
  2. use App\Models\Quest;
  3. use Sti3bas\ScoutArray\Facades\Search;
  4. use function Pest\Laravel\{actingAs};
  5. use Illuminate\Foundation\Testing\RefreshDatabase;
  6. // Necessary to access Laravel testing helpers and database factory stuff
  7. uses(
  8. Tests\TestCase::class,
  9. RefreshDatabase::class
  10. )->group('search');
  11. // Auto set up a new authed user for each test
  12. beforeEach(function () {
  13. actingAs(User::factory()->create());
  14. });
  15. /**
  16. * Tests that the quest is synced to the search index
  17. */
  18. it('Test Created Quests are Synced to Search Index', function () {
  19. // Get the current authed user to associate the quest to
  20. $quest = Quest::factory()->create([
  21. 'user_id' => auth()->id()
  22. ]);
  23. // Ensure the quest is synced to the search index
  24. Search::assertSynced($quest);
  25. });
  26. /**
  27. * Tests the quest data format in the search index is correct
  28. */
  29. it('Test Created Quests Exist in the Search Index', function () {
  30. // Get the current authed user to associate the quest to
  31. $quest = Quest::factory()->create([
  32. 'user_id' => auth()->id()
  33. ]);
  34. // Ensure the quest data format is correct in search index
  35. Search::assertContains($quest)
  36. ->assertContains($quest, function ($record) use ($quest) {
  37. // Note how I'm only using a subset to test instead of $request = $quest->toArray()?
  38. // That's because the search index adds some extra fields and $quest->toArray() strips some db added fields
  39. return [
  40. 'id' => $record['id'],
  41. 'name' => $record['name'],
  42. 'description' => $record['description'],
  43. 'user_id' => $record['user_id'],
  44. ] == [
  45. 'id' => $quest->id,
  46. 'name' => $quest->name,
  47. 'description' => $quest->description,
  48. 'user_id' => $quest->user_id,
  49. ];
  50. });
  51. });
  52. /**
  53. * Tests the search functionality of the Quest model
  54. */
  55. it('Test Search Quest Is Correct', function () {
  56. // Get the current authed user to associate the quest to
  57. $quest = Quest::factory()->create([
  58. 'user_id' => auth()->id()
  59. ]);
  60. // Search for the just created quest by name
  61. $questSearch = Quest::search($quest->name)->where('user_id', $quest->user_id)->get();
  62. // Make sure we only have one result
  63. expect($questSearch)
  64. ->toHaveCount(1);
  65. // Make sure search results match the quest we created
  66. expect($questSearch->first()->toArray())
  67. ->toMatchArray($quest->toArray());
  68. });

huangapple
  • 本文由 发表于 2023年2月27日 09:18:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576074.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定