PhpUnit:如何伪造一个过时的文件?

PhpUnit: how to fake an outdated file?

我在 class 中有一个方法,它检查文件是否超过一天。它通过获取文件的最后更改日期并将其与“现在”进行比较来实现这一点:


    private function checkFileOutdated(string $filePath): bool
    {
        if (file_exists($filePath)) {
            $fileTimeStamp = filectime($filePath);

            $now = new DateTimeImmutable();
            $fileDate = new DateTimeImmutable('@' . $fileTimeStamp);
            $diff = (int) $now->format('Ymd') - (int) $fileDate->format('Ymd');

            return $diff > 0;
        }

        return true;
    }

我想编写一个伪造过时文件的单元测试。我试图通过触摸更改文件日期:

        $location = '/var/www/var/xls/myfile.xlsx';
        $handle = fopen($location, 'wb');
        fclose($handle);
        exec('touch -a -m -t 202109231158 ' . $location);
        exec('ls -hl ' . $location, $output);
        var_dump($output);

输出给我的信息实际上是我的文件来自“9 月 23 日 11:58”,是的......

但是我的测试失败了,当我调试时我的文件日期是今天而不是 9 月 23 日。

使用 filemtime 结果相同。

是否可以伪造文件时间戳?

我的系统在高山上运行 linux。

请注意,您不必先创建文件,因为 touch 会为您完成。 PHP 内置 touch(),你不必 shell exec:

touch('/tmp/foo', strtotime('-1 day'));
echo date('r', fileatime('/tmp/foo')), "\n";
echo date('r', filectime('/tmp/foo')), "\n";
echo date('r', filemtime('/tmp/foo')), "\n";

这产生:

Tue, 02 Nov 2021 12:18:17 -0400
Wed, 03 Nov 2021 12:18:17 -0400
Tue, 02 Nov 2021 12:18:17 -0400

正在应用您的代码,但使用 filemtime:

$fileTimeStamp = filemtime($filePath);
$now = new DateTimeImmutable();
$fileDate = new DateTimeImmutable('@' . $fileTimeStamp);
$diff = (int) $now->format('Ymd') - (int) $fileDate->format('Ymd');
var_dump($diff);

产生所需的真值:

1

然而,这是一个相当迂回的比较。我只是直接比较时间戳值:

return filemtime('/tmp/foo') <= strtotime('-1 day');

只需删除 -a 和 -m 选项。 来自手册:

-a     change only the access time
-m     change only the modification time

使用这 2 个选项时,创建时间仍然完好无损。