Feature: Add Tests for Extract Action#178
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request introduces comprehensive feature tests for the extraction actions across different sites (Japan, Portal, and Twitrans), verifying content extraction, last modified date parsing, and handler invocation. The review feedback suggests refactoring ExtractActionTest.php to use Mockery instead of manual anonymous classes and state objects, which would make the tests more concise and idiomatic.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| public function test_invokes_handlers_for_all_sites_when_null_provided(): void | ||
| { | ||
| $state = (object) ['japan' => false, 'portal' => false, 'twitrans' => false]; | ||
|
|
||
| $this->app->bind(Handler::class, function () use ($state) { | ||
| return new class($state) implements HandlerInterface | ||
| { | ||
| public function __construct(private object $state) {} | ||
|
|
||
| public function __invoke(LoggerInterface $logger): void | ||
| { | ||
| $this->state->japan = true; | ||
| } | ||
| }; | ||
| }); | ||
|
|
||
| $this->app->bind(\App\Actions\Extract\Portal\Handler::class, function () use ($state) { | ||
| return new class($state) implements HandlerInterface | ||
| { | ||
| public function __construct(private object $state) {} | ||
|
|
||
| public function __invoke(LoggerInterface $logger): void | ||
| { | ||
| $this->state->portal = true; | ||
| } | ||
| }; | ||
| }); | ||
|
|
||
| $this->app->bind(\App\Actions\Extract\Twitrans\Handler::class, function () use ($state) { | ||
| return new class($state) implements HandlerInterface | ||
| { | ||
| public function __construct(private object $state) {} | ||
|
|
||
| public function __invoke(LoggerInterface $logger): void | ||
| { | ||
| $this->state->twitrans = true; | ||
| } | ||
| }; | ||
| }); | ||
|
|
||
| $action = app(ExtractAction::class); | ||
| $action(null, new NullLogger); | ||
|
|
||
| $this->assertTrue($state->japan); | ||
| $this->assertTrue($state->portal); | ||
| $this->assertTrue($state->twitrans); | ||
| } |
There was a problem hiding this comment.
ハンドラーが呼び出されたことを検証するために、冗長な匿名クラスや手動の $state オブジェクトを使用する代わりに、Mockery を使用してハンドラークラスをモック化し、期待値(once())を設定することをお勧めします。これにより、テストがより簡潔で読みやすく、かつ慣用的(idiomatic)になります。
public function test_invokes_handlers_for_all_sites_when_null_provided(): void
{
$japanHandler = \Mockery::mock(Handler::class);
$japanHandler->shouldReceive('__invoke')->once();
$this->app->instance(Handler::class, $japanHandler);
$portalHandler = \Mockery::mock(\App\Actions\Extract\Portal\Handler::class);
$portalHandler->shouldReceive('__invoke')->once();
$this->app->instance(\App\Actions\Extract\Portal\Handler::class, $portalHandler);
$twitransHandler = \Mockery::mock(\App\Actions\Extract\Twitrans\Handler::class);
$twitransHandler->shouldReceive('__invoke')->once();
$this->app->instance(\App\Actions\Extract\Twitrans\Handler::class, $twitransHandler);
$action = app(ExtractAction::class);
$action(null, new NullLogger);
}| public function test_invokes_specific_handler_when_site_provided(): void | ||
| { | ||
| $state = (object) ['japan' => false, 'portal' => false, 'twitrans' => false]; | ||
|
|
||
| $this->app->bind(Handler::class, function () use ($state) { | ||
| return new class($state) implements HandlerInterface | ||
| { | ||
| public function __construct(private object $state) {} | ||
|
|
||
| public function __invoke(LoggerInterface $logger): void | ||
| { | ||
| $this->state->japan = true; | ||
| } | ||
| }; | ||
| }); | ||
|
|
||
| $this->app->bind(\App\Actions\Extract\Portal\Handler::class, function () use ($state) { | ||
| return new class($state) implements HandlerInterface | ||
| { | ||
| public function __construct(private object $state) {} | ||
|
|
||
| public function __invoke(LoggerInterface $logger): void | ||
| { | ||
| $this->state->portal = true; | ||
| } | ||
| }; | ||
| }); | ||
|
|
||
| $this->app->bind(\App\Actions\Extract\Twitrans\Handler::class, function () use ($state) { | ||
| return new class($state) implements HandlerInterface | ||
| { | ||
| public function __construct(private object $state) {} | ||
|
|
||
| public function __invoke(LoggerInterface $logger): void | ||
| { | ||
| $this->state->twitrans = true; | ||
| } | ||
| }; | ||
| }); | ||
|
|
||
| $action = app(ExtractAction::class); | ||
| $action(SiteName::Japan, new NullLogger); | ||
|
|
||
| $this->assertTrue($state->japan); | ||
| $this->assertFalse($state->portal); | ||
| $this->assertFalse($state->twitrans); | ||
| } |
There was a problem hiding this comment.
同様に、Mockery を使用して特定のハンドラーのみが呼び出され(once())、他のハンドラーは呼び出されないこと(never())を検証できます。これにより、テストコードが大幅にシンプルになります。
public function test_invokes_specific_handler_when_site_provided(): void
{
$japanHandler = \Mockery::mock(Handler::class);
$japanHandler->shouldReceive('__invoke')->once();
$this->app->instance(Handler::class, $japanHandler);
$portalHandler = \Mockery::mock(\App\Actions\Extract\Portal\Handler::class);
$portalHandler->shouldReceive('__invoke')->never();
$this->app->instance(\App\Actions\Extract\Portal\Handler::class, $portalHandler);
$twitransHandler = \Mockery::mock(\App\Actions\Extract\Twitrans\Handler::class);
$twitransHandler->shouldReceive('__invoke')->never();
$this->app->instance(\App\Actions\Extract\Twitrans\Handler::class, $twitransHandler);
$action = app(ExtractAction::class);
$action(SiteName::Japan, new NullLogger);
}|
ご指摘ありがとうございます!ご提案の通り、ExtractActionTest.php を Mockery を利用してリファクタリングし、匿名クラスと状態オブジェクトを削除してシンプルにしました。修正をPushしました。 |
ExtractActionおよび関連する各サイト(Japan, Portal, Twitrans)のExtractContents、ExtractLastModified処理に対するテストを追加しました。