2015-02-04 4 views
0

두 클래스가 있는데, PHPUnit을 통해 테스트하고 싶습니다. 하지만 나는 물건을 조롱 할 때 잘못했다. 첫 번째 클래스에서 호출 한 메서드를 변경하고 싶습니다.모의를 사용하여 PHPUnit 모의

class One { 
    private $someVar = null; 
    private $abc = null; 

    public function Start() { 
     if (null == $this->someVar) { 
      $abc = (bool)$this->Helper(); 
     } 

     return $abc; 
    } 

    public function Helper() { 
     return new Two(); 
    } 


} 
Class Two { 
    public function Check($whateverwhynot) { 
     return 1; 
    } 
} 


Class testOne extends PHPUnit_Framework_TestCase { 
    public function testStart() { 
     $mockedService = $this 
      ->getMockBuilder(
       'Two', 
       array('Check') 
      ) 
      ->getMock(); 

     $mockedService 
      ->expects($this->once()) 
      ->method('Check') 
      ->with('13') 
      ->will($this->returnValue(true)); 

     $mock = $this 
      ->getMockBuilder(
       'One', 
       array('Helper')) 
      ->disableOriginalConstructor() 
      ->getMock(); 

     $mock 
      ->expects($this->once()) 
      ->method('Helper') 
      ->will($this->returnValue($mockedService)); 

     $result = $mock->Start(); 
     $this->assertFalse($result); 
    } 
} 

그리고 $result 대신 'true'의, NULL이다의 결과는

내가 어설 줄을 사용하지 않으면, 내가 오류 메시지가 얻을

:

F 

Time: 0 seconds, Memory: 13.00Mb 

There was 1 failure: 

1) testOne::testStart 
Expectation failed for method name is equal to <string:Check> when invoked 1 time(s). 
Method was expected to be called 1 times, actually called 0 times. 

아이디어 ?

업데이트 - 환경 : PHP의 5.4.3x, phpunit을 3.7.19 - 중요한 것은 : 당신은 ouzo-goodies에서 모의 ​​객체를 사용하여 원래의 클래스 (클래스 하나와 클래스 두)

+2

PHPUnit은 의존성 주입을 위해 작동합니다. 조롱 된 두 클래스를 하나에 주입해야합니다. 또한 getMockBuilder 메소드의 매개 변수를 올바르게 사용하지 않았습니다. – SenseException

+0

어디서 getMockBuilder를 잘못 사용합니까? 두 번째 mocked 클래스를 첫 번째 클래스에 삽입하려면 어떻게해야합니까? 어떤 예제 나 문서 또는 그 어떤 것도 발견하지 못했습니다. 링크 나 뭔가를 놓을 수 있습니까? – huncyrus

답변

0

모의를 잘못 작성하는 중입니다. $this->getMockBuilder()을 사용하고 있습니다.이 인수는 조롱 할 클래스의 이름을 하나만 취합니다. 여러 개를 취하는 $this->getMock()과 (과) 병합하는 것 같습니다.

변경에 테스트 : 우리는 우리가 테스트 모의 클래스를 필요로하고 있지만 당신은 당신의 모든 클래스를 변경할 수 없습니다 언급하기 때문에 좋은 시험하지

public function testStart() { 
    $mockedService = $this 
     ->getMockBuilder('Two') 
     ->setMethods(array('Check')) 
     ->getMock(); 

    $mockedService 
     ->expects($this->once()) 
     ->method('Check') 
     ->with('13') 
     ->will($this->returnValue(true)); 

    $mock = $this 
     ->getMockBuilder('One') 
     ->setMethods(array('Helper')) 
     ->disableOriginalConstructor() 
     ->getMock(); 

    $mock 
     ->expects($this->once()) 
     ->method('Helper') 
     ->will($this->returnValue($mockedService)); 

    $result = $mock->Start(); 
    $this->assertFalse($result); 
} 

.

+1

도움을 주셔서 감사합니다. 다른 경우에는 주사도 작동 && 예, 나는 정말로 mockbuilder를 잘못 사용합니다. 다시 한 번 감사드립니다! – huncyrus

+2

종속성 주입을 사용하지만 클래스를 변경할 수없는 경우 클래스를 리팩토링하는 것이 좋습니다 ... – Schleis

2

을 수정할 수 없습니다.

클래스 :

생성자 분사 객체 Two에서
class One 
{ 
    private $someVar = null; 
    private $abc = null; 
    private $two; 

    public function __construct(Two $two) 
    { 
     $this->two = $two; 
    } 

    public function Start() 
    { 
     if (null == $this->someVar) { 
      $abc = (bool)$this->Helper()->Check(1213); 
     } 

     return $abc; 
    } 

    public function Helper() 
    { 
     return $this->two; 
    } 
} 

, 그래서 당신은 쉽게 객체를 조롱 할 수 있습니다.

class Two 
{ 
    public function Check($whateverwhynot) 
    { 
     return 1; 
    } 
} 

그리고 시험 : mocks에 대한

class OneTest extends PHPUnit_Framework_TestCase 
{ 
    /** 
    * @test 
    */ 
    public function shouldCheckStart() 
    { 
     //given 
     $mock = Mock::create('\Two'); 
     Mock::when($mock)->Check(Mock::any())->thenReturn(true); 

     $one = new One($mock); 

     //when 
     $start = $one->Start(); 

     //then 
     $this->assertTrue($start); 
    } 
} 

문서.

+0

좋은 점, 고맙습니다! ....하지만 주된 문제는 원래 One과 Two 클래스를 수정할 수 없으며 테스트를 위해 타사 라이브러리를 사용할 수 없다는 것입니다. – huncyrus

관련 문제