단위 테스트를 작성할 때 중요한 과제는 테스트가 외부 시스템이나 종속성의 간섭 없이 테스트 중인 코드에 초점을 맞추도록 하는 것입니다. 여기가 PHPUnit에서 모의 객체가 작동하는 곳입니다. 이를 통해 제어된 방식으로 실제 객체의 동작을 시뮬레이션할 수 있으므로 테스트가 더욱 안정적이고 유지 관리가 쉬워집니다. 이 글에서는 모의 객체가 무엇인지, 왜 유용한지, PHPUnit에서 효과적으로 사용하는 방법을 살펴보겠습니다.
모의 객체는 단위 테스트에 사용되는 실제 객체의 시뮬레이션 버전입니다. 이를 통해 다음을 수행할 수 있습니다.
모의는 다음 시나리오에서 특히 유용합니다.
모의 개체로 작업할 때 스터빙과 모의:
라는 두 가지 용어를 접하게 됩니다.PHPUnit을 사용하면 createMock() 메서드를 사용하여 모의 객체를 쉽게 만들고 사용할 수 있습니다. 다음은 모의 객체를 효과적으로 사용하는 방법을 보여주는 몇 가지 예입니다.
이 예에서는 클래스 종속성에 대한 모의 객체를 만들고 해당 동작을 지정합니다.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { public function testMockExample() { // Create a mock for the SomeClass dependency $mock = $this->createMock(SomeClass::class); // Specify that when the someMethod method is called, it returns 'mocked value' $mock->method('someMethod') ->willReturn('mocked value'); // Pass the mock object to the class under test $unitUnderTest = new ClassUnderTest($mock); // Perform the action and assert that the result matches the expected value $result = $unitUnderTest->performAction(); $this->assertEquals('expected result', $result); } }
설명:
경우에 따라 올바른 매개변수를 사용하여 메소드가 호출되는지 확인해야 합니다. 그렇게 하는 방법은 다음과 같습니다.
public function testMethodCallVerification() { // Create a mock object $mock = $this->createMock(SomeClass::class); // Expect the someMethod to be called once with 'expected argument' $mock->expects($this->once()) ->method('someMethod') ->with($this->equalTo('expected argument')) ->willReturn('mocked value'); // Pass the mock to the class under test $unitUnderTest = new ClassUnderTest($mock); // Perform an action that calls the mock's method $unitUnderTest->performAction(); }
핵심 사항:
모의 객체의 실제 적용을 보여주기 위해 외부 PaymentGateway 인터페이스에 의존하는 PaymentProcessor 클래스의 예를 들어보겠습니다. 우리는 PaymentGateway의 실제 구현에 의존하지 않고 PaymentProcessor의 processPayment 메소드를 테스트하고 싶습니다.
PaymentProcessor 클래스는 다음과 같습니다.
class PaymentProcessor { private $gateway; public function __construct(PaymentGateway $gateway) { $this->gateway = $gateway; } public function processPayment(float $amount): bool { return $this->gateway->charge($amount); } }
이제 실제 결제 게이트웨이와 상호작용하지 않고 processPayment 메소드를 테스트하기 위해 PaymentGateway에 대한 모의를 생성할 수 있습니다.
use PHPUnit\Framework\TestCase; class PaymentProcessorTest extends TestCase { public function testProcessPayment() { // Create a mock object for the PaymentGateway interface $gatewayMock = $this->createMock(PaymentGateway::class); // Define the expected behavior of the mock $gatewayMock->method('charge') ->with(100.0) ->willReturn(true); // Inject the mock into the PaymentProcessor $paymentProcessor = new PaymentProcessor($gatewayMock); // Assert that processPayment returns true $this->assertTrue($paymentProcessor->processPayment(100.0)); } }
테스트 분석:
결제를 처리할 때 청구 방법이 정확히 한 번 호출되는지 확인할 수도 있습니다.
public function testProcessPaymentCallsCharge() { $gatewayMock = $this->createMock(PaymentGateway::class); // Expect the charge method to be called once with the argument 100.0 $gatewayMock->expects($this->once()) ->method('charge') ->with(100.0) ->willReturn(true); $paymentProcessor = new PaymentProcessor($gatewayMock); $paymentProcessor->processPayment(100.0); }
이 예에서 Expects($this->once())는 청구 메소드가 정확히 한 번 호출되도록 보장합니다. 메서드가 호출되지 않거나 두 번 이상 호출되면 테스트가 실패합니다.
사용자 데이터를 가져오기 위해 UserRepository에 의존하는 UserService 클래스가 있다고 가정해 보겠습니다. UserService를 독립적으로 테스트하려면 UserRepository를 모의할 수 있습니다.
class UserService { private $repository; public function __construct(UserRepository $repository) { $this->repository = $repository; } public function getUserName($id) { $user = $this->repository->find($id); return $user->name; } }
이 클래스를 테스트하기 위해 저장소를 모의할 수 있습니다.
use PHPUnit\Framework\TestCase; class UserServiceTest extends TestCase { public function testGetUserName() { // Create a mock for the UserRepository $mockRepo = $this->createMock(UserRepository::class); // Define that the find method should return a user object with a predefined name $mockRepo->method('find') ->willReturn((object) ['name' => 'John Doe']); // Instantiate the UserService with the mock repository $service = new UserService($mockRepo); // Assert that the getUserName method returns 'John Doe' $this->assertEquals('John Doe', $service->getUserName(1)); } }
모의 객체는 PHPUnit에서 단위 테스트를 작성하는 데 매우 유용한 도구입니다. 이를 통해 코드를 외부 종속성으로부터 격리할 수 있으므로 테스트가 더 빠르고 안정적이며 유지 관리가 더 쉬워집니다. 또한 모의 객체는 테스트 중인 코드와 해당 종속성 간의 상호 작용을 확인하여 코드가 다양한 시나리오에서 올바르게 작동하는지 확인하는 데 도움이 됩니다
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3