백엔드 개발 PHP 튜토리얼 PHP: 조롱해야 할까요, 아니면 가야 할까요?

PHP: 조롱해야 할까요, 아니면 가야 할까요?

Dec 11, 2024 am 10:36 AM

PHP: Should I mock or should I go?

간단히 말해서 모의

모의는 실제 물체의 거동을 테스트하는 것을 목표로 합니다.

종속성을 시뮬레이션하므로 단위 테스트 속도를 크게 저하시킬 수 있는 외부 리소스를 호출할 필요가 없습니다.

기대를 정의하고 검증할 수 있습니다.

예를 들어 메소드가 특정 횟수 및/또는 특정 매개변수를 사용하여 호출되도록 할 수 있습니다.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    public function testMockExample(): void
    {
        $depencencyMock = $this->createMock(MyDependency::class);

        $dependencyMock->expects($this->exactly(2))
              ->method('someMethod')
              ->with('some parameter');

        $classToTest = new ClassToTest($dependencyMock);
   }
}
로그인 후 복사
로그인 후 복사

반환 값

willReturn()은 반환 유형과의 호환성을 보장합니다.

// In code
class MyClass {
    public function getNum(): int {
    }
}

// In tests
$myClassMock = $this->createMock(MyClass::class);
$myClassMock->expects($this->once())
            ->method('getNum')
            ->willReturn(2);
로그인 후 복사

입력 매개변수를 기반으로 동적 동작을 테스트하려는 경우 willReturnCallback을 사용할 수도 있습니다.

피해야 할 나쁜 습관

모의는 실제 동작을 모방하기 때문에 요점을 놓치기 쉽습니다. 일반적인 나쁜 관행에 대해 논의해 보겠습니다.

기대 없이 값 반환

❌ 그러지 마세요:

$colorServiceMock = $this->createMock(ColorService::class);
$colorServiceMock->method('hexToName')
     ->willReturn('red');

$color = (new MyClass($colorServiceMock))->getColorName('ff0000');
로그인 후 복사

✅ 대신에 몇 가지 기대치를 추가하세요.

$colorServiceMock->expects($this->once())
     ->method('hexToName')
     ->with('00f00')
     ->willReturn('green');

$color = (new MyClass($colorServiceMock))->getColorName('00f00');
로그인 후 복사

모의의 목적은 상호 작용을 확인하는 것임을 기억하세요.

인터페이스 대신 실제 객체를 모의합니다.

SomeInterface를 구현한 MyClass를 테스트해 보겠습니다.

❌ 그러지 마세요:

$myclassMock = $this->createMock(MyClass::class);
로그인 후 복사

✅ 대신 인터페이스를 모의하세요:

$myclassMock = $this->createMock(SomeInterface::class);
로그인 후 복사

모의는 행동에 중점을 둡니다. 계약이 아닌 구현을 수정해야 하므로 인터페이스는 일반적으로 변경되지 않습니다.

과도한 모의 테스트

Tomas Votruba는 이 문제를 훌륭하게 설명합니다. 과잉 모의 테스트에서 가치를 추출하는 5가지 방법

잘못된 디자인 관행을 가리기 위해 모의 객체를 사용하기

구성요소 간의 긴밀한 결합을 무시하기 쉽습니다.

$productRepositoryMock = $this->createMock(ProductRepository::class);
$invoiceRepositoryMock = $this->createMock(InvoiceRepository::class);
$emailServiceMock = $this->createMock(EmailService::class);

$overComplexService = new OverComplexService($productRepositoryMock, $invoiceRepositoryMock, $emailServiceMock);
로그인 후 복사

위의 예는 우려 사항의 분리를 무너뜨렸고, Mock은 이러한 나쁜 습관을 영속시키고 있습니다.

모의 객체에만 의존

Mock은 강력한 도구이지만 단위 테스트만으로는 충분하지 않습니다. 그 밖에도 다양한 유형의 테스트(예: 통합, e2e)가 필요합니다.

모의 객체의 잘못된 사용을 알아내는 방법

나쁜 관행 외에도 프로젝트에서 모의 ​​객체가 오용되거나 과도하게 사용되었음을 나타낼 수 있는 다른 징후가 있습니다.

  • 테스트는 실제 시나리오를 반영하지 않으며 생산 시 중요한 문제를 간과합니다
  • 테스트와 구현 사이에는 긴밀한 결합이 있어 관련 모의 항목이 자주 업데이트됩니다
  • 테스트가 너무 복잡해서 읽고 유지 관리하기가 더 어렵습니다

모의 및 스텁

Martin Fowler는 Mocks가 Stubs가 아닌 이유를 설명하는 환상적인 게시물을 작성했습니다.

이를 사용할 수 있는 구체적인 상황을 살펴보겠습니다.

모의를 사용하는 경우

다음은 모의 테스트가 더 적합한 몇 가지 테스트 사례입니다.

  • 클래스가 종속성과 어떻게 상호작용하는지 테스트해야 합니다
  • 특정 메소드가 다른 매개변수로 여러 번 호출되는 복잡한 시퀀스를 확인해야 합니다

스텁을 사용하는 경우

PHPUnit을 사용하면 매우 편리하게 스텁을 만들 수 있습니다.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    public function testMockExample(): void
    {
        $depencencyMock = $this->createMock(MyDependency::class);

        $dependencyMock->expects($this->exactly(2))
              ->method('someMethod')
              ->with('some parameter');

        $classToTest = new ClassToTest($dependencyMock);
   }
}
로그인 후 복사
로그인 후 복사

다음은 스텁이 더 적합한 몇 가지 테스트 사례입니다.

  • 상호작용을 확인할 필요 없이 코드의 출력이나 상태를 테스트하려는 경우
  • 실제 데이터베이스와 상호작용할 필요 없이 일부 계산을 테스트해야 합니다

간단히 말하면 스텁은 실제 객체의 동작을 확인하기 위한 것이 아니라 상태를 확인하기 위한 것입니다.

미세 조정

단위 테스트의 주요 목적은 각 단위/구성 요소가 예상대로 작동하는지 확인하는 것이지만, 실제 코드 외에 이러한 테스트도 유지해야 합니다.

스텁은 테스트 설정을 단순화할 수 있으며 메서드 호출 및 상호 작용을 추적할 필요가 없는 간단한 시나리오에 매우 효율적입니다.

일부 테스트에 집중하여 불필요한 복잡성을 방지할 수 있습니다.

마무리

모의는 메소드 호출과 해당 매개변수를 추적할 수 있습니다.

실제 동작을 대표하는 값을 반환하는 것을 잊지 마세요. 그렇지 않으면 잘못된 안보의식을 갖게 될 수도 있습니다.

Mock은 유지 관리에 불필요한 복잡성을 피하기 위해 자제해서 사용해야 합니다.

위 내용은 PHP: 조롱해야 할까요, 아니면 가야 할까요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) 11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) Mar 03, 2025 am 10:49 AM

11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄)

Instagram API 소개 Instagram API 소개 Mar 02, 2025 am 09:32 AM

Instagram API 소개

Laravel의 플래시 세션 데이터로 작업합니다 Laravel의 플래시 세션 데이터로 작업합니다 Mar 12, 2025 pm 05:08 PM

Laravel의 플래시 세션 데이터로 작업합니다

Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Mar 12, 2025 pm 05:09 PM

Laravel 테스트에서 단순화 된 HTTP 응답 조롱

PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 Mar 14, 2025 am 11:42 AM

PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법

Laravel Back End : Part 2, React가있는 React 앱 구축 Laravel Back End : Part 2, React가있는 React 앱 구축 Mar 04, 2025 am 09:33 AM

Laravel Back End : Part 2, React가있는 React 앱 구축

Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Mar 13, 2025 pm 12:08 PM

Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트

라 라벨에서 알림 라 라벨에서 알림 Mar 04, 2025 am 09:22 AM

라 라벨에서 알림

See all articles