Nice programing

phpunit 모의 생성자 인수를 피하십시오

nicepro 2020. 10. 4. 13:24
반응형

phpunit 모의 생성자 인수를 피하십시오


phpunit이 모의 객체에 대한 생성자를 호출하는 것을 피하는 방법은 무엇입니까? 그렇지 않으면 생성자 인수로 모의 객체가 필요하고 그에 대한 또 다른 객체가 필요합니다. api는 다음과 같이 보입니다.

getMock($className, $methods = array(), array $arguments = array(),
        $mockClassName = '', $callOriginalConstructor = TRUE,
        $callOriginalClone = TRUE, $callAutoload = TRUE)

작동하지 않습니다. $callOriginalConstructorfalse 설정된 경우에도 생성자 인수에 대해 여전히 불평합니다 .

생성자에는 하나의 개체 만 있으며 종속성 주입입니다. 그래서 저는 거기에 디자인 문제가 없다고 생각합니다.


getMockBuilder대신 사용할 수 있습니다 getMock.

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

섹션을 참조하십시오 "테스트 복식"phpunit을 설명서에서 자세한 내용을.

할 수 있지만 할 필요가없는 것이 훨씬 낫습니다. 삽입해야하는 구체적인 클래스 (생성자가있는) 대신 인터페이스에만 의존하도록 코드를 리팩토링 할 수 있습니다. 즉, 생성자 동작을 수정하도록 PHPUnit에 지시 할 필요없이 인터페이스를 모의하거나 스텁 할 수 있습니다.


여기 있습니다 :

    // Get a Mock Soap Client object to work with.
    $classToMock = 'SoapClient';
    $methodsToMock = array('__getFunctions');
    $mockConstructorParams = array('fake wsdl url', array());
    $mockClassName = 'MyMockSoapClient';
    $callMockConstructor = false;
    $mockSoapClient = $this->getMock($classToMock,
                                     $methodsToMock,
                                     $mockConstructorParams,
                                     $mockClassName,
                                     $callMockConstructor);

부록으로 expects()모의 객체 호출을 첨부 한 다음 생성자를 호출하고 싶었습니다 . PHPUnit 3.7.14에서 호출 할 때 반환 disableOriginalConstructor()되는 객체는 말 그대로 객체입니다.

// Use a trick to create a new object of a class
// without invoking its constructor.
$object = unserialize(
sprintf('O:%d:"%s":0:{}', strlen($className), $className)

불행히도 PHP 5.4에는 사용하지 않는 새로운 옵션이 있습니다.

ReflectionClass :: newInstanceWithoutConstructor

이것은 사용할 수 없기 때문에 수동으로 클래스를 반영한 ​​다음 생성자를 호출해야했습니다.

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

$mock->expect($this->once())
    ->method('functionCallFromConstructor')
    ->with($this->equalTo('someValue'));

$reflectedClass = new ReflectionClass('class_name');
$constructor = $reflectedClass->getConstructor();
$constructor->invoke($mock);

Note, if functionCallFromConstruct is protected, you specifically have to use setMethods() so that the protected method is mocked. Example:

    $mock->setMethods(array('functionCallFromConstructor'));

setMethods() must be called before the expect() call. Personally, I chain this after disableOriginalConstructor() but before getMock().


Perhaps you need to create a stub to pass in as the constructor argument. Then you can break that chain of mock objects.


Alternatively you could add a parameter to getMock to prevent the calling of the default constructor.

$mock = $this->getMock(class_name, methods = array(), args = array(), 
        mockClassName = '', callOriginalConstructor = FALSE);

Still, I think the answer of dave1010 looks nicer, this is just for the sake of completeness.


PHPUnit is designed to call the constructor on mocked objects; to prevent this you should either:

  1. Inject a mock object as a dependency into the object you're having trouble mocking
  2. Create a test class that extends the class you're trying to call that doesn't call the parent constructor

참고URL : https://stackoverflow.com/questions/279493/phpunit-avoid-constructor-arguments-for-mock

반응형