제품 코드의 필수 모듈식 with PHP51

12786 단어 PHP

혼자 모형 만들자.


안녕하세요ω゜)ノ
이번에는 PHPUnit으로 UnitTest를 쓸 때 중요한 mock을 쓰는 독특한 방법을 만들었습니다.
PHPUnit의 버전을 올릴 때 개작 방법 등이 필요하지 않다는 이유에서다.
시험을 쓰기 전에 진급을 해야 한다고 하지만 쉽지 않은 어른들의 경우도 있다

runket 함수 사용하기


이번에 PHP의 runket 함수를 사용하여 방법을 설명한다.
이 함수를 사용하면 방법과 삽입식 함수의 처리를 동적으로 바꿀 수 있고, 유무 불문하고 지울 수 있는 중독의 위력을 발휘할 수 있는 마법이다.
이 함수를 사용해 원래 방법을 덮은 가죽을 만드는 것은 작전이다.
이번에는 예를 들어 다음과 같은 방법으로 step를 만든다.
class TestClass {
    public function add10($a) {
        return $a + $this->return10();
    }

    private function return10(){
        return 10;
    }
}
이번 목표는요.
  • return10() 제작 방법의 보존, return10() 10 이외의 값
  • 을 반환
  • add10() 실제 return10()
  • 기타 테스트 용례에 영향을 주지 않음
  • 네.
    이번 목적은 step를 만들어 테스트 코드를 원활하게 쓰는 것이기 때문에 테스트 드라이브 개발(TDD)을 적용해 추진하려고 한다.그래서 이상적인 테스트 코드를 먼저 쓰세요.
    class TestClassTest extends TestClass {
        public function test_generate_return10のスタブを作ること() {
            RunkitStub::generate('TestClass', 'return10', 50);
            $instance = new TestClass();
            $result = $instance->add10(10);
            $this->assertSame(60, $result);
        }
    
        public function tearDown() {
            RunkitStub::revertAll();
        }
    }
    
    TestClassTest 등 다양한 구설의 학급명이 됐지만, ←
    이 테스트를 통해 어느 정도generate()의 규격을 공고히 하는 동시에 설치할 수 있다.generate()의 매개 변수는 순서대로 クラス名, メソッド名, 期待する戻り値이다.

    runket 함수를 사용하여 마침내 정적 방법을 실현하였다


    그럼 실제 실시내용은
    절차는 다음과 같습니다. ※다음은 번거롭기 때문에TestClass의 코드를'정식 코드'라고 부른다.
  • 정식 코드의 클래스 이름과 방법 이름을 받아들여 무작위 문자열
  • 로 고친다
  • 방법 이름과 무작위 문자열을 연결하기 위해 속성에 겹치기
  • 상응하는 방법명과 같은 명칭의 가짜 방법을 제작한다(이때 가짜 방법의 내용은 매개 변수로 받은 값으로만 되돌려준다)
  • 가짜 방법이 정식 코드로 위장된 기간에 테스트를 실시
  • 테스트 종료 후 가짜 방법을 삭제하고 속성에서 정식 코드를 추출하여 원래의 이름을 변경
  • 이해하기 어려울 수도 있지만 주로 정식 코드와 같은 이름의 짝퉁 코드를 만들어 테스트를 진행할 때 상대방에게 이런 상당히 강제적인 방법을 대행하도록 한다.
    그럼 갑시다ω゜)ノ

    1. 공식 코드의 클래스 이름과 방법 이름을 받아들여 무작위 문자열로 이름 바꾸기


    우선, 받은 방법의 이름을 바꾸어야 한다.
    이때 주의해야 할 것은 이름을 바꿀 때 유일한 값이어야 하며, 이름을 바꾸기 전에 원래의 클래스 이름과 방법 이름에서 끊을 수 없다는 것이다.
    방법명을 무작위 문자열로 변환하는 처리는 여기서 hash() 등을 사용하려고 하지만 해시 값으로 바뀌면 같은 테스트 용례에서 같은 법명을 여러 번 보류할 때 같은 방법명으로 바뀌어 오류가 발생할 수 있습니다.
    이번에 나는 uniqid()라는 물건을 사용했는데'dummy'라는 문자열에서 독특한 문자열을 생성했다.
    $tmp_hashed_method_name = uniqid('dummy_');
    runkit_method_rename($class_name, $method_name, $tmp_hashed_method_name);
    

    2. 방법 명칭과 무작위 문자열을 연결하기 위해 속성으로 연상 배열 창고


    정식 코드의 방법에 가죽을 임시로 덮어쓰더라도 독특한 값과 방법의 정보를 속성에 저장할 수 있다.
    만약 이렇게 하지 않는다면 시험이 끝난 후에는 정식 코드를 복구할 수 없을 것이다.이게 제일 고민인 것 같아요.
    먼저 클래스의 배열 속성을 설명합니다.
    
    private static $stashed_methods = array();
    
    정의된 속성에는 독특한 값과 클래스 이름, 방법 이름이 포함되어 있습니다.
    
    self::$stashed_methods[] = array(
            'class_name'   => $class_name,
            'method_name'  => $method_name,
            'hashed_name'  => $hashed_name
    );
    
    이렇게 하면 정식 공연의 코드를 안전하게 피할 수 있다.

    3. 이 방법의 이름과 같은 이름을 가진 가짜 방법을 만듭니다(이 때 가짜 방법의 내용은 지정한 반환값만 되돌려줍니다).


    그럼 본공연 때 짝퉁 군을 등장시켜 주세요.
    여기,runkitmethod_매개 변수로 받은 클래스 이름과 방법 이름, 되돌아오는 값에 따라dd를 사용하여 보존 방법을 만듭니다.
    runkit_method_add($class_name, $method_name, '', "return $return;");
    
    runkit_method_dd의 매개 변수와 상세한 내용은 공식 문서를 참조하십시오.
    이 줄에서 매개 변수로 받은 값을 되돌려 주는 방법을 만들 수 있습니다!대단하다!!

    4. 가짜 방법이 정식 코드로 위장되었을 때 테스트


    힘내세요.

    5. 테스트가 끝난 후 가짜 방법에서 사라지십시오(이 처리는 티어다운에 기재되어 이후의 테스트 용례에 영향을 미치지 않습니다)


    그럼 지금은 가짜를 제거할 시간입니다.
    테스트가 끝난 후 제작 상태를 없애지 않으면 이후의 테스트와 커버에 큰 영향을 미칠 수 있다.
    여기서 주의해야 할 것은 뒤에 있는 스타벅스부터 순서대로 삭제하고 속성의 내용을 모두 삭제하는 것이다.
    먼저 뒤에 있는 스타벅스부터 순서대로 사라지기 시작한 이유는 하나의 테스트 용례에서 스타벅스를 여러 번 생성한 경우 문제가 발생하지 않기 때문이다.
    두 번째 이후 생성된 스타벅스는 이전 처리로 만들어진 스타벅스이기 때문이다.
    이상한 일본어로 말하면 안 돼요. 한 테스트 용례가 여러 번 step를 생성한 상황에서 뒤에서 답장을 하지 않으면 중간에 잘 안 맞아요.이러한 상황을 방지하기 위해 속성에 쌓인 방법을 하나하나 팝업합니다.
    
    while(!empty(self::$stashed_methods)){
        $origin = array_pop(self::$stashed_methods);
        runkit_method_remove($origin['class_name'], $origin['method_name']);
        runkit_method_rename($origin['class_name'], $origin['hashed_name'], $origin['method_name']);
    }
    
    이렇게 하면 아래의 테스트 용례에 쓸데없는 정보를 전달하지 않고 아무 일도 없는 것처럼 테스트를 끝낼 수 있다.

    하마를 구경하다


    실제 RunkitStub 레벨을 사용하여 테스트를 수행하여 덮어쓰기를 확인합니다.
    상기 테스트 코드를 실행하고 덮어쓰는 상황이 다음과 같으면 return10()의 상태가 양호하다는 것을 증명합니다.

    총결산


    총괄해 보면 이런 느낌이다.
    <?php
    class RunkitStub {
    
    private static $stashed_methods = array();
    
    protected function generate($class_name, $method_name, $return) {
        $hashed_name = uniqid('Dummy__'); //同じメソッド名でも違う値になるようuniqidを使用
        runkit_method_rename($class_name, $method_name, $hashed_name);
    
        self::$stashed_methods[] = array(
            'class_name'   => $class_name,
            'method_name'  => $method_name,
            'hashed_name'  => $hashed_name
        );
    
        runkit_method_add($class_name, $method_name, '', "return $return;");
    }
    
    protected function revertAll() {
        while(!empty(self::$stashed_methods)){
            $origin = array_pop(self::$stashed_methods);
            runkit_method_remove($origin['class_name'], $origin['method_name']);
            runkit_method_rename($origin['class_name'], $origin['hashed_name'], 
    $origin['method_name']);
        }
    }
    
    상당히 강압적인 방법이기 때문에 마음대로 하면 욕을 먹을 수 있으니 흉내 낼 때는 스스로 책임지세요.

    참고 자료


    [runket 함수]
    http://php.net/manual/ja/ref.runkit.php

    좋은 웹페이지 즐겨찾기