Skip to content

Commit 9dcf04b

Browse files
committed
Add functional tests for the new Symfony module assertions
Cover the assertions added in codeception/module-symfony: assertSessionHasFlashMessage(), the console ExecutionResult assertions, mockService(), seeNumQueriesIsLessThan()/dontSeeDuplicateQueries() and the Messenger in-memory transport assertions. Add the matching app fixtures: a flash-and-redirect controller (/flash), a ResultCommand exercising success / failure / invalid / stderr for runCommand(), a Greeting service behind /greeting to swap with mockService(), a query-heavy /run-queries page for the Doctrine query-count assertions, and an in-memory async transport with SendWelcomeMessage routed to it.
1 parent 56fde86 commit 9dcf04b

13 files changed

Lines changed: 201 additions & 0 deletions

‎config/packages/messenger.yaml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ framework:
55
default_bus: messenger.bus.default
66
buses:
77
messenger.bus.default: ~
8+
transports:
9+
async: 'in-memory://'
10+
routing:
11+
App\Message\SendWelcomeMessage: async

‎config/routes.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
use App\Controller\DashboardController;
77
use App\Controller\DomCrawlerController;
88
use App\Controller\ExternalApiController;
9+
use App\Controller\FlashController;
910
use App\Controller\FormController;
11+
use App\Controller\GreetingController;
1012
use App\Controller\HomeController;
1113
use App\Controller\HttpClientController;
1214
use App\Controller\RegistrationController;
15+
use App\Controller\RunQueriesController;
1316
use App\Controller\SecurityController;
1417
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
1518

@@ -109,4 +112,16 @@
109112
$routes->add('dispatch_message', '/dispatch-message')
110113
->controller(App\Controller\DispatchMessageController::class)
111114
->methods(['GET']);
115+
116+
$routes->add('app_flash', '/flash')
117+
->controller(FlashController::class)
118+
->methods(['GET']);
119+
120+
$routes->add('app_greeting', '/greeting')
121+
->controller(GreetingController::class)
122+
->methods(['GET']);
123+
124+
$routes->add('app_run_queries', '/run-queries')
125+
->controller(RunQueriesController::class)
126+
->methods(['GET']);
112127
};

‎config/services_test.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
declare(strict_types=1);
44

5+
use App\Service\Greeting;
56
use Symfony\Bundle\SecurityBundle\Security;
67
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
78

@@ -10,4 +11,8 @@
1011

1112
$services->alias(Security::class, 'security.helper')
1213
->public();
14+
15+
$services->set(Greeting::class)
16+
->autowire()
17+
->public();
1318
};

‎src/Command/ResultCommand.php‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Command;
6+
7+
use Symfony\Component\Console\Attribute\AsCommand;
8+
use Symfony\Component\Console\Command\Command;
9+
use Symfony\Component\Console\Input\InputInterface;
10+
use Symfony\Component\Console\Input\InputOption;
11+
use Symfony\Component\Console\Output\ConsoleOutputInterface;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
14+
#[AsCommand(ResultCommand::COMMAND_NAME, 'A command exercising the execution result paths.')]
15+
final class ResultCommand extends Command
16+
{
17+
public const COMMAND_NAME = 'app:result-command';
18+
19+
protected function configure(): void
20+
{
21+
$this->addOption('fail', null, InputOption::VALUE_NONE);
22+
$this->addOption('invalid', null, InputOption::VALUE_NONE);
23+
}
24+
25+
protected function execute(InputInterface $input, OutputInterface $output): int
26+
{
27+
if ($input->getOption('invalid')) {
28+
$output->writeln('Invalid input.');
29+
30+
return Command::INVALID;
31+
}
32+
33+
if ($input->getOption('fail')) {
34+
if ($output instanceof ConsoleOutputInterface) {
35+
$output->getErrorOutput()->writeln('Something failed.');
36+
}
37+
38+
return Command::FAILURE;
39+
}
40+
41+
$output->writeln('All good.');
42+
43+
return Command::SUCCESS;
44+
}
45+
}

‎src/Controller/FlashController.php‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Controller;
6+
7+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
8+
use Symfony\Component\HttpFoundation\RedirectResponse;
9+
10+
final class FlashController extends AbstractController
11+
{
12+
public function __invoke(): RedirectResponse
13+
{
14+
$this->addFlash('success', 'Welcome back!');
15+
16+
return $this->redirectToRoute('index');
17+
}
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Controller;
6+
7+
use App\Service\Greeting;
8+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
9+
use Symfony\Component\HttpFoundation\Response;
10+
11+
final class GreetingController extends AbstractController
12+
{
13+
public function __construct(
14+
private readonly Greeting $greeting,
15+
) {
16+
}
17+
18+
public function __invoke(): Response
19+
{
20+
return new Response($this->greeting->greet());
21+
}
22+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Controller;
6+
7+
use App\Repository\UserRepository;
8+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
9+
use Symfony\Component\HttpFoundation\Response;
10+
11+
final class RunQueriesController extends AbstractController
12+
{
13+
public function __construct(
14+
private readonly UserRepository $users,
15+
) {
16+
}
17+
18+
public function __invoke(): Response
19+
{
20+
$this->users->findAll();
21+
$this->users->getByEmail('john_doe@gmail.com');
22+
23+
return new Response('Queries executed.');
24+
}
25+
}

‎src/Service/Greeting.php‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Service;
6+
7+
class Greeting
8+
{
9+
public function greet(): string
10+
{
11+
return 'Hello world!';
12+
}
13+
}

‎tests/Functional/ConsoleCest.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace App\Tests\Functional;
66

77
use App\Command\ExampleCommand;
8+
use App\Command\ResultCommand;
89
use App\Tests\Support\FunctionalTester;
910

1011
final class ConsoleCest
@@ -29,4 +30,15 @@ public function runSymfonyConsoleCommand(FunctionalTester $I)
2930
);
3031
$I->assertStringContainsString('Bye world!', $output);
3132
}
33+
34+
public function consoleExecutionResult(FunctionalTester $I): void
35+
{
36+
$I->assertCommandIsSuccessful($I->runCommand(ResultCommand::COMMAND_NAME));
37+
$I->assertCommandFailed($I->runCommand(ResultCommand::COMMAND_NAME, ['--fail' => true]));
38+
$I->assertCommandIsInvalid($I->runCommand(ResultCommand::COMMAND_NAME, ['--invalid' => true]));
39+
40+
$result = $I->runCommand(ResultCommand::COMMAND_NAME, ['--fail' => true]);
41+
$I->assertStringContainsString('Something failed.', $result->getErrorOutput());
42+
$I->assertCommandResultEquals($result, expectedStatusCode: 1);
43+
}
3244
}

‎tests/Functional/DoctrineCest.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,11 @@ public function seeNumRecords(FunctionalTester $I)
4343
{
4444
$I->seeNumRecords(1, User::class);
4545
}
46+
47+
public function queryCountAssertions(FunctionalTester $I): void
48+
{
49+
$I->amOnPage('/run-queries');
50+
$I->seeNumQueriesIsLessThan(10);
51+
$I->dontSeeDuplicateQueries();
52+
}
4653
}

0 commit comments

Comments
 (0)