2012-02-22 3 views
28

PHPUnit으로 PHP 코드를 단위 테스트 할 때, 메소드를 조롱하지 않고 객체를 조롱하는 정확한 방법을 찾아 내려고하고 있습니다.어떤 방법을 조롱하지 않고 phpunit에서 모의 ​​작성하기?

getMockBuilder()->setMethods()을 호출하지 않으면 개체의 모든 메서드가 조롱을 받아 테스트 할 메서드를 호출 할 수 없습니다. 그러나 내가 이라면 setMethods()으로 전화해라. 그러면 내가 어떤 방법을 조롱 하는지를 말해야한다. 그러나 나는 어떤 방법을 조롱하고 싶지 않다. 하지만 테스트에서 생성자를 호출하지 않도록 모의 작업을 만들어야합니다. 내가 가진 myMethod() 테스트 할 수

class Foobar 
{ 
    public function __construct() 
    { 
     // stuff happens here ... 
    } 

    public function myMethod($s) 
    { 
     // I want to test this 
     return (strlen($s) > 3); 
    } 
} 

: 여기

내가 테스트 할 것입니다 방법의 사소한 예입니다

$obj = new Foobar(); 
$this->assertTrue($obj->myMethod('abcd')); 

을하지만 내가하지 않습니다는 foobar의 생성자를 호출 것 필요. 그래서 그 대신 내가 시도 할 것 : 모든 메소드가 발생합니다 setMethods()를 사용하지 않고

$obj = $this->getMockBuilder('Foobar')->disableOriginalConstructor()->getMock(); 
$this->assertTrue($obj->myMethod('abcd')); 

그러나 호출 getMockBuilder() 조롱하고 null이 반환되고, 그래서 myMethod()에 내 전화는 내가 테스트하려는 코드를 건드리지 않고 null를 돌려줍니다.

내 해결 방법은 지금까지이있다 :

$obj = $this->getMockBuilder('Foobar')->setMethods(array('none')) 
    ->disableOriginalConstructor()->getMock(); 
$this->assertTrue($obj->myMethod('abcd')); 

이 존재하지 않는 '아무도'라는 이름없는 방법을 조롱하지만, phpunit을 상관하지 않습니다. myMethod()를 잠금 해제하여 호출 할 수있게하고, 호출하지 않도록 생성자를 비활성화 할 수도 있습니다. 완전한! 그것은 존재하지 않는 메소드 이름을 지정해야하는 바람을 피우는 것만 큼 - 'none'또는 'blargh'또는 'xyzzy'처럼 보입니다.

이 작업을 수행하는 올바른 방법은 무엇입니까?

답변

38

어떤 방법을 조롱하지 않으려면 nullsetMethods()으로 전달할 수 있습니다. 빈 배열을 전달하면 모든 메소드를 모방합니다. 후자는 발견 한 메소드의 기본값입니다.

내가 말했듯이,이 작업을 수행해야 할 필요성이이 클래스의 디자인 결함을 지적 할 수 있습니다. 이 메소드를 정적으로 만들거나 다른 클래스로 이동해야합니까? 이 메소드가 완전하게 구축 된 인스턴스를 필요로하지 않는다면 그것은 정적으로 만들 수있는 유틸리티 메소드 일 수 있다는 신호입니다.

+3

대단히 감사합니다. setMethods (null)는 내가 원하는 것입니다; 이로 인해 조롱을받을 방법이 없습니다. 반면에 setMethods (array())는 setMethods()를 사용하지 않는 것과 마찬가지로 모든 메소드가 조롱당하는 것처럼 보입니다. 나는 어디서나이 문서를 찾을 수 없었다. 그래도 "빈 부모"란 뜻은 무엇입니까? –

+0

또한 - 귀하의 의견에 의아해합니다. 위에 제공된 사소한 myMethod() 예제의 세부 사항을 제외하고,이 방법으로 테스트해야하는 메소드를 사용하면 메소드를 다른 클래스로 이동하거나 정적으로 만들어야한다고 느끼게되는 이유는 무엇입니까? –

+0

@BrianKendig - "parens"인 "parents"에서 자동 고침이 실패합니다. :) 방금 소스를 확인 했으므로 기본값이 없으므로 직접 null을 전달해야합니다. –

3

또 다른 해키하지만, 간결 솔루션은 조롱 방법 중 하나로 마법의 생성자를 나열하는 것입니다 : 이것은 나를 위해 일한

$mock = $this->getMock('MyClass', array('__construct')); 
-8

:

$this->getMock($class, array(), array(), '', false); 
+0

요점이 완전히 누락되었습니다 – dVaffection

0

아니면 그냥 직접 getMock()을 사용할 수 있습니다 .

$mock = $this->getMock('MyClass', null, array(), null, false);

+0

getMock()은 더 이상 지원되지 않습니다 – krazyweb

+0

예. 내가 받아 들인 대답에 투표했다. – Ryan

관련 문제