2013-05-30 4 views
4

이것은 조롱에 대한 나의 편에 대한 오해 일 수 있습니다. 존재하지 않거나 존재하는 클래스를 조롱하는 것이 왜 좋은지에 대한 설명에 정말 감사하겠습니다.PHP 단위 테스트 및 조롱과 조롱

예제 시나리오 : 한 클래스가 두 번째 클래스의 출력에 종속되어 있고 출력 형식이나 기타를 변경한다고 가정 해보십시오. 첫 번째 수업에서 구식이지만 테스트가 성공적으로 유지되지 않겠습니까?

답변

4

대답은 예입니다! 코드에서 일부 테스트 가능성 원칙을 존중하는 경우 동일한 클래스의 다른 테스트 방법과 한 테스트 방법을 분리 할 수 ​​있습니다. 그것이 유닛 테스트의 목표입니다. 테스트는 방법 months가 깨진 경우에도 전달합니다

<?php 

class User { 

    public function years() 
    { 
     return floor($this->months()/12); 
    } 

    public function months() 
    { 
     // Database call or anything else, it's a black box ! 
    } 

} 

class UserTest extends TestCase { 

    public function testYearsReturnTheNumberOfYears() 
    { 
     $user = \Mockery::mock('User[months]'); 
     $user->shouldReceive('months')->andReturn(18); 

     assertEquals(1, $user->years()); 
    } 

} 

:

이 예를 참조하십시오. 자세한 설명은 mockery documentation을 읽어보십시오.

조롱은 단위 테스트의 열쇠입니다. 이 도구가 없으면 코드에서 무언가 문제가 발생하면 모든 테스트가 실패하고 오류의 원인을 찾을 수 없습니다. PHP는 Ruby 나 Javascript와 같은 모든 것을 조롱 할만큼 유연하지 않지만 훌륭한 디자인 패턴을 사용하면 훌륭한 작업을 수행 할 수 있습니다.

모든 핵심 클래스를 조롱 할 수있는 아주 좋은 예가 Laravel입니다. 이와 같이 데이터베이스 호출이나 이메일 전송에서 실수를 시뮬레이션 할 수 있습니다.

+0

답변 감사합니다! 필자는 최근 며칠 동안 조롱에 익숙해졌으며, 특히 Dependency Injection과 함께 사용할 때 더욱 그렇습니다. 여전히 혼란 스럽긴하지만, 조롱 된 클래스에서 출력이 변경되면 다른 테스트의 모의이 여전히 동일한 후미 출력을 반환합니다. 즉,'''User [months]'''를 고려하면, 메소드는 정수 대신에''''MyNamespace \ Month''의 인스턴스를 반환합니다. '''UserTest''가 관계없이 성공하지 않을까요? 그것은하지 않아도되지만?! 반환 값을 int로 사용 했으므로 이제는 인스턴스입니다. – Mulkave

+0

mock 객체는 실제 구현과는 완전히 독립적입니다. 그래서 yes,'months'가 정수를 리턴하면 테스트는 다시 통과 할 것입니다. 'User' 클래스에서'months' 메소드를 삭제하면 테스트가 다시 통과합니다. 'months' 메소드보다 먼저'years' 메소드를 쓰고 싶다면 (예를 들어, 다른 팀의 작업 인 경우) 이것은 특히 유용합니다. –

+0

그것에 대해 더 이상의 설명이 필요하지 않은 경우. 귀하의 질문을 닫지 잊지 마세요;) –

1

비슷한 문제가있었습니다. 의존성 주입으로 같은 클래스 방법을 모의해야만했던 곳. 조롱에 따라서 부분적인 망신 시켰습니다 ...이 사람을 도움이 될 것입니다

$mock = Mockery::mock('MyClass[methodToMock1, methodToMock2]', array('constructor parameter 1', 'constructor parameter 2')); 
$mock->shouldReceive('methodToMock1')->once()->andReturn('someValue'); 
$mock->shouldReceive('methodToMock2')->once()->andReturn('someValue2'); 
$this->assertTrue($mock->methodNum3(), 'some assert'); 

희망.