我仅使用 symfony/console 库来创建一个小型 cli 应用程序。
我想按原样对命令进行单元测试,但单元测试没有提供输出。
这是我的单元测试设置:
class TimrOverviewCommandTest extends TestCase
{
public function testTimrOverviewCommand()
{
$input = new ArgvInput(argv: [
"overview",
"--csv",
"tests/csv/day_report.csv"
]);
$buffered = new BufferedOutput();
$app = new Timr(__DIR__);
$exitCode = $app->run($input, $buffered);
$result = $buffered->fetch();
$this::assertSame(actual: $result, expected: "2024-10-18: Expected 5 / Delivered 5.25\n");
}
}
这就是我的应用程序的设置方式:
class Timr
{
private readonly Application $app;
public function __construct(string $rootDir)
{
$parser = new CsvParser($rootDir);
$app = new Application('timr', '1.0.0');
$app->add(new TimrReportCommand($parser));
$app->add(new TimrOverviewCommand($parser));
$this->app = $app;
}
public function run(?InputInterface $input = null, ?OutputInterface $output = null): int
{
return $this->app->run($input, $output);
}
}
有几个相关的问题,但其中大多数似乎都在整个 symfony Web 应用程序的范围内和/或已经过时了:
有两个陷阱:
argv
又名tokens
数组的第一项将在ArgvInput
构造函数中删除:
$argv ??= $_SERVER['argv'] ?? [];
// strip the application name
array_shift($argv);
$this->tokens = $argv;
解决方案:将另一个项目添加到您的argv数组中:
$input = new ArgvInput(argv: [
"name", // will be stripped
"overview",
"--csv",
"tests/csv/day_report.csv"
]);
另一个问题是应用程序在任务完成后完全关闭的默认行为。这是通过
autoexit
标志处理的:
App::run
if ($this->autoExit) {
if ($exitCode > 255) {
$exitCode = 255;
}
exit($exitCode);
}
return $exitCode;
解决方案:禁用应用程序定义中的标志。
$app = new Application('timr', '1.0.0');
$app->setAutoExit(false);