をバンドルすると、すぐにDateTimeクラスのすべての使用法を模擬することは現実的ではなくなりました。
私はこれを行うために見つけた最良の方法が延びて自分のDateTimeクラスを実装することである
など、それはこのようなテストクッキーやキャッシュの有効期限などの時間をかけてリクエストを処理するようアプリケーションをテストしたかったですその時点以降に作成されるすべてのDateTimeオブジェクトにデフォルトの時間スキューを追加/減算するための静的メソッドをいくつか提供します。
これは実装が非常に簡単な機能で、カスタムライブラリをインストールする必要はありません。
警告の買い手
:この方法の唯一の欠点は、symfonyフレームワーク(または使用しているものは何でもフレームワーク)ですが、あなたのライブラリーを使用することはありませんので、このような内部キャッシュ/クッキーなど、それ自体を処理するために期待されます任意の行動、これらの変更によって影響を受けることはありません。これを使用する
namespace My\AppBundle\Util;
/**
* Class DateTime
*
* Allows unit-testing of DateTime dependent functions
*/
class DateTime extends \DateTime
{
/** @var \DateInterval|null */
private static $defaultTimeOffset;
public function __construct($time = 'now', \DateTimeZone $timezone = null)
{
parent::__construct($time, $timezone);
if (self::$defaultTimeOffset && $this->isRelativeTime($time)) {
$this->modify(self::$defaultTimeOffset);
}
}
/**
* Determines whether to apply the default time offset
*
* @param string $time
* @return bool
*/
public function isRelativeTime($time)
{
if($time === 'now') {
//important, otherwise we get infinite recursion
return true;
}
$base = new \DateTime('2000-01-01T01:01:01+00:00');
$base->modify($time);
$test = new \DateTime('2001-01-01T01:01:01+00:00');
$test->modify($time);
return ($base->format('c') !== $test->format('c'));
}
/**
* Apply a time modification to all future calls to create a DateTime instance relative to the current time
* This method does not have any effect on existing DateTime objects already created.
*
* @param string $modify
*/
public static function setDefaultTimeOffset($modify)
{
self::$defaultTimeOffset = $modify ?: null;
}
/**
* @return int the unix timestamp, number of seconds since the Epoch (Jan 1st 1970, 00:00:00)
*/
public static function getUnixTime()
{
return (int)(new self)->format('U');
}
}
は単純です:
public class myTestClass() {
public function testMockingDateTimeObject()
{
echo "fixed: ". (new DateTime('18th June 2016'))->format('c') . "\n";
echo "before: ". (new DateTime('tomorrow'))->format('c') . "\n";
echo "before: ". (new DateTime())->format('c') . "\n";
DateTime::setDefaultTimeOffset('+25 hours');
echo "fixed: ". (new DateTime('18th June 2016'))->format('c') . "\n";
echo "after: ". (new DateTime('tomorrow'))->format('c') . "\n";
echo "after: ". (new DateTime())->format('c') . "\n";
// fixed: 2016-06-18T00:00:00+00:00 <-- stayed same
// before: 2016-09-20T00:00:00+00:00
// before: 2016-09-19T11:59:17+00:00
// fixed: 2016-06-18T00:00:00+00:00 <-- stayed same
// after: 2016-09-21T01:00:00+00:00 <-- added 25 hours
// after: 2016-09-20T12:59:17+00:00 <-- added 25 hours
}
}
あなたはまだ答えを受け入れませんでした。あなたは、あなたが何を求めているのか、またその答えがあなたを満足させない理由を明確にしてください。 – Gordon
ちょうど同じ問題を抱えていたので、@shouzeの答えからのphp timecop拡張は魅力的だった。 –