2014-07-14 5 views
0

새로운 버전의 자체를 생성하고 데이터베이스에 삽입하는 클래스의 테스트를 작성하고 있습니다. insert 메소드는 원본 클래스에 대해 이처럼 약간 기록하고자하는 id를 반환합니다.PHPUnit가 여러 인스턴스화를위한 메소드 스터 빙

class Invoice { 

    public function creditInvoice() { 
     $credit = new static(); 
     // .... 
     $creditId = $credit->insert(); 
     $this->credited_by = $creditId; 
     $this->update(); 
     return $credit; 
    } 

} 

내 테스트는 송장 클래스를 조롱하고 업데이트 및 삽입을 대체합니다. 그런 다음 insert를 id를 반환하는 함수로 바꿉니다.

class InvoiceTest { 

    public function testCreditInvoice { 
     $invoice = $this->getMock('Invoice', array('update', 'insert')); 
     $invoice->expects($this->any()) 
       ->method('insert') 
       ->will($this->returnValue(1234)); 

     $credit = $invoice->creditInvoice(); 
     $this->assertTrue(
      $invoice->credited_by == 1234 
     ); 
    } 

} 

이것은 실패합니다. new static()이 mock 클래스의 새 버전을 올바르게 작성했지만 오버라이드 된 메소드를 가지고 있지 않으므로 credited_by이 실제로 null 인 것 같습니다.

이 문제를 해결할 수있는 유일한 방법은 Invoice를 상속하지만 삽입 기능을 재정의하여 테스트 데이터를 반환하는 새 테스트 클래스를 만드는 것입니다. 그러나 이것은 나에게 좋은 습관이 아닙니다.

더 좋은 방법이 있습니까?

+0

사람들이'new static()'이 나쁜 습관이라고 생각한다면 테스트중인 코드를 변경할 수 있습니다. – DanielM

+0

나는 의존성 주입을 사용하여 문제를 해결했다. 그러나 객체를 전달하는 것은 자신의 클래스도 빈 상태 여야하고, 실제로 나에게 좋은 코딩 방법처럼 보이지 않는다. (아마도 나는 틀렸다). 문제의 상황을 변화시키지 않는 해결책이있는 사람이라면 누구나 그 의견을 듣는 것이 좋습니다. – DanielM

답변

0

new static은 새로운 기대치가없는 MockInvoice을 반환합니다. 이것이 시험이 효과가없는 이유입니다. 새로운 객체는 단순한 모의 객체입니다.

insert 메서드를 호출하기 위해 클래스의 새 인스턴스를 만드는 이유가 다소 혼란 스럽습니다. 왜 $this->insert()으로 전화하지 않으시겠습니까? 그렇다면 걱정할 필요가 없습니다 new static().

IMO, 테스트중인 클래스 모의를 작성하는 것은 좋지 않습니다. 그것은 당신이 데이터베이스에 데이터를 추가하는 것 그리고 나는 insertupdate 별도의 클래스의 메서드로 것입니다. 그러나 당신의 예제 코드는 당신이 이루고자하는 것이 무엇인지에 대한 완전한 아이디어를 얻으려면 약간 희소하다.

+0

매우 잘 설명되지 않은 경우 죄송합니다. '...'는 "여기에서 일어나는 일들"을위한 자리 표시 자일뿐입니다. 그것은 Invoice를 대표하는 객체이며, 해당 Invoice에 대한 Credit을 만들고 싶습니다. 이 경우 크레디트는 신용 유형, 동일한 오브젝트의 송장이므로 생성하고 송장 데이터를 사용하여 크레딧을 생성합니다. 'new static()'은 그것을위한 것이지 테스트는 아닙니다. 나중에 클래스를 상속받을 경우를 대비해서 항상'self'보다는'static'을 사용합니다. – DanielM