2012-11-14 4 views
9

모의 객체와 반대로 phpunit을 사용하여 모의 클래스를 만드는 방법이 있습니까? 클래스를 생성자 (또는 어디서나)에서 작업해야 할 수도있는 모든 객체를 명시 적으로 전달하지 않고 종속성 삽입을 수행하는 방법을 찾고 있습니다. 이 모든 경우에 대해 "true"를 반환합니다 뭔가 :phpunit으로 모의 수업을 만드시겠습니까?

public function testAAAA() 
{ 
    $foo = $this->getMock('foo', array('bar')); 
    var_dump(class_exists('foo', false)); 
    var_dump(method_exists('foo', 'bar')); 
    var_dump(method_exists($foo, 'bar')); 
} 

이 인쇄 :

bool(true) 
bool(false) 
bool(true) 

성공적 가짜 'foo는'클래스를 생성 않았다 동안은 '줄을 결합하지 않은 것을 나타내는 '방법을 사용합니다.

저는 phpunit 3.7.5를 사용하고 있습니다.

답변

10

내가 당신이 실제로 (당신이 the docs를 참조 phpunit을의 mockbuilder와 등등 생성자를 사용하지 않고 수)이 작업을 수행 할 수없는 것으로 생각하지만, 당신이 원하는 또는 필요 않는 가정이 트릭을 수행해야합니다

$foo = $this->getMockBuilder('nonexistant') 
     ->setMockClassName('foo') 
     ->setMethods(array('bar')) 
     ->getMock(); 

    var_dump(class_exists('foo', false)); 
    var_dump(method_exists('foo', 'bar')); 
    var_dump(method_exists($foo, 'bar')); 

    $cls = new ReflectionClass('foo'); 
    var_dump($cls->hasMethod('bar')); 

나는 왜 위에서 다른 이름 (nonexistant와 foo)을 지정해야하는지 명확히 모르겠다.하지만 조롱당하는 클래스가 아직 존재하지 않을 때 PHPUnit의 행동과 관련이있는 것으로 보인다. setMockClassName을 사용하면 해당 클래스를 확장하는 클래스를 생성 할 수 있습니다. 또는 뭔가. 아마 효과적으로 버그/가장자리 - 사건을 해결하려고 노력하고 있습니다 - 이것은 도서관의 이상한 사용법입니다. getMock 기능만으로도 똑같은 작업을 수행 할 수 있어야합니다.

제쳐두고, 아마도 php's reflection capabilities에 익숙해 져야하는 것처럼 들립니다. 그곳에서 가장 강력한 리플렉션 라이브러리가 아니지만 꽤 좋습니다. 필자는 생성자 인수 및 올바른 "유형"값을 허용하는 양식을 생성하는 데 사용되는 "모델"라이브러리의 속성을 기반으로 클래스의 필수 및 선택적 필드에 대한 메타 정보를 생성하는 데 사용했습니다. 즉, 양식이 필요한 클래스의 인스턴스없이 형식화 된 양식을 생성하고 손으로 쓰지 않고도 바보 같은 양의 코드를 작성하지 않아도됩니다. 전체 기능의 경우 약 100 줄입니다. 분명히 내가하려는 일을 알지는 못하지만, 게시물의 소량 정보에서 볼 때, 나는 그 유형의 메타 것보다 더 가깝다고 생각합니다.

+0

필자는 필연적으로이 작업을 원한다고 말하지는 않겠지 만, 내가해야하는 작업입니다. 수만 개의 파일을 변경하지 않고 테스트 내에서 호출에 응답 할 모의 객체를 생성 할 수 있어야합니다. 이 getMockBuilder 메소드는 나를 가까이에 가져 오지만, phpunit이 네임 스페이스 모의 클래스 이름 (원래 포스트에서 언급 했어야하는 것을 사용하고있는 것)으로 호출 될 때 잘못된 평가 코드를 생성하는 것처럼 보입니다. –

+0

'getMock()'호출 다음에'class_alias ('foo', 'quux \ baz')'와 같은'class_alias' 호출을 추가하고'quux \ baz'에 대해 테스트하십시오. 즉, 기본적으로 PHPUnit 패치를 적용하거나 ReflectionClass 및 ReflectionObject의 기능을 사용하여 객체 또는 클래스에 즉시 추가 할 수있는 시점에 있다고 생각합니다. 그러면 가장자리의 경우가 될 것입니다. 이것은 PHP가 빛나는 영역이 아닙니다. 또한 읽지 않은 경우 Michael Feathers의 "Legacy Code With Effective With Legacy Code"사본이 필요합니다. – jeremiahd

+0

감사합니다. 나는 class_alias를 시도 할 것이다. 또한 PHPUnit을 패치하여 eval()에서 사용하는 템플릿을 수정합니다. 이 책에 관해서는, 내가 정말로 필요로하는 것은 상사가 읽을 것을 얻는 것이다. :) –

관련 문제