将对象与PHPUnit中的DateTime属性进行比较

时间:2017-10-25 13:14:20

标签: php datetime phpunit

假设我有两个具有以下结构的对象:

class Item {
     public $id;
     public $date;
}

在单元测试中,我想测试两个项目的相等性。 E.g:

class MyTests extends PHPUnit\Framework\TestCase
{
    public function testDummy() {
        $item1 = new Item();
        $item1->id = 1000;
        $item1->date = new DateTimeImmutable('now');

        $item2 = new Item();
        $item2->id = 1000;
        $item2->date = $item1->date->modify('+1 second');

        // For my use case, I'd consider these two items equal.
        $this::assertEquals($item1, $item2); // FAILURE :(
}

是否有一种干净/简单的方法比较这些对象并在PHPUnit遇到DateTime对象时使用delta?

我知道我可以使用$this::assertEquals($item1->date, $item2->date, '', 10)但是根据我的目标,我宁愿不为每个属性编写断言。

谢谢!

3 个答案:

答案 0 :(得分:0)

$ item1 = date(' D,d M Y');

$ item2 =日期(' D,d M Y',strtotime(" +1天"));

试试这个

答案 1 :(得分:0)

不确定在给定的测试用例中,您需要的[测试结果]类型的基础是什么。但是如果你想测试两个对象是否相等:

  • 根据[实例]
  • 比较两个对象
  • 如果存在一个属性使用[DateTime]对象
  • 的情况

然后我会建议ff。断言:

class MyTests extends PHPUnit\Framework\TestCase
{
    public function testDummy() {
        $item1 = new Item();
        $item1->id = 1000;
        $item1->date = new DateTimeImmutable('now');

        $item2 = new Item();
        $item2->id = 1000;
        $item2->date = $item1->date->modify('+1 second');

        // Option 1: Check if given object is an instance of [Item] class
        $this::assertEquals($item1 instanceof Item, $item2 instanceof Item);

        // Option 2: Check if given property for each assigned variables is an instance of [DateTimeImmutable] class
        $this::assertEquals($item1->date instanceof DateTimeImmutable, $item2->date instanceof DateTimeImmutable);
    }
}

希望这能指导你。

答案 2 :(得分:0)

我建议您在equals课程中实施Item方法,并在测试中测试其返回值,如下所示:

class MyTests extends PHPUnit\Framework\TestCase
{
    public function testDummy() {
        $item1 = new Item();
        $item1->id = 1000;
        $item1->date = new DateTimeImmutable('now');

        $item2 = new Item();
        $item2->id = 1000;
        $item2->date = $item1->date->modify('+1 second');

        $this->asserTrue($item1->equals($item2));
        $this->asserTrue($item2->equals($item1));
    }
}

对于与此类似的Item

class Item
{
    const OFFSET_TOLERANCE = 1;

    public $id;
    public $date;

    public function equals(self $item): bool
    {
        // in case the id is relevant as well
        if ($this->id !== $item->id) {
            return false;
        }

        // not sure how you prefer to handle the following 2 cases
        if (null === $item->date && null === $this->date) {
            return true;
        }

        if (!($this->date instanceof DateTimeInterface) ||
            !($item->date instanceof DateTimeInterface))
        {
            return false;
        }

        $interval = $this->date->diff($item->date);

        // note that you can also use $interval->f
        // to compare microseconds since PHP 7.1
        return $interval->s > self::OFFSET_TOLERANCE;
    }
}

不幸的是,Java中没有__equals方法。

我能想到的唯一替代解决方案是实现一个__toString方法,该方法返回Item对象的某种代表性值,包含没有最后一位数的时间戳。

但就可读性和可靠性而言,为了确保您明确了解您的实施,我建议您寻求类似于上述示例的解决方案。