2017-10-25 2 views
0

에 날짜 시간 특성을 가진 개체 비교 : 단위 테스트에서내가이 다음과 같은 구조의 객체가 있다고 가정 phpunit을

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

을, 나는 두 항목의 평등을 테스트하고 싶습니다. 예컨대 :

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 :(
} 

이러한 개체를 비교하고 DateTime 개체를 발견 phpunit을 경우에 델타를 사용하여 깨끗한/간단한 방법이 있나요?

나는 $this::assertEquals($item1->date, $item2->date, '', 10)을 사용할 수 있지만 내 객체에 대해서는 각 속성에 대한 어설 션을 작성하지 않을 것이라고 알고 있습니다.

감사합니다.

+0

두 인스턴스는 어떻게 같습니까? 'date' 속성은 1 초 간격으로 있습니다. 귀하의 유스 케이스에 대해 "동등"한 것은 무엇입니까? – ishegg

+0

왜 1 초를 추가하고 그것이 동일하다고 생각하니? DateTime에는 밀리 초가 있습니다. – DanFromGermany

+0

예제로 사용하는 사례는 이해가되지 않습니다. 물론 두 객체의 내용이 동일하게 설정되면 동일합니다. 당신이 더 편안함을 원한다면, 나는'Reflection'을 들여다 볼 것입니다. – DanFromGermany

답변

0

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

$ item2 = 날짜 ('D, d M Y', strtotime ("+ 1 day"));

가 [테스트 결과]의 종류에 기초가 될 것입니다 무엇인지이

0

하지 않으려 고이 주어진 테스트 케이스에 대한 필요가있다. 당신이 테스트하려는 경우 그러나 두 개체가 동일한 경우 : 하나의 속성이 (가) [날짜 시간] 개체를 사용하는 경우가 있다면

  • 가 [예]
  • 에 따라 두 개체를 비교

그러면 나는 그 제안을하겠다. 단언 :

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); 
    } 
} 

희망이 있으면 도움이 될 것입니다.

0

나는 당신의 Item 클래스에 equals 방법을 구현하고 그냥이 같은 테스트에서 반환 값을 테스트하는 것이 좋습니다 것 :

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; 
    } 
} 
: 이것과 유사한 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)); 
    } 
} 

자바와 마찬가지로 __equals 메서드가 없습니다.

내가 생각할 수있는 유일한 대안은 Item 개체의 대표 값을 반환하는 __toString 메서드를 구현하는 것입니다. 즉, 마지막 숫자가없는 타임 스탬프를 포함합니다.

하지만 가독성과 안정성 측면에서 사용자가 구현 방법을 명확히 나타내도록 위의 예와 비슷한 해결책을 제안합니다.