phpunit이 모의 객체에 대해 컨스트럭터를 호출하지 않아도 되는 방법은 무엇입니까?그렇지 않으면 나는 컨스트럭터 인수로 모의 객체가 필요하게 될 것이고, 그것을 위해 다른 객체가 필요하게 될 것이다.API는 다음과 같습니다.
getMock($className, $methods = array(), array $arguments = array(),
$mockClassName = '', $callOriginalConstructor = TRUE,
$callOriginalClone = TRUE, $callAutoload = TRUE)
작동이 안 돼요.그것은 여전히 건설자의 주장에 대해 불평하고 있다.$callOriginalConstructor
false로 설정합니다.
생성자에 개체가 하나뿐이고 종속성 주입입니다.그래서 저는 거기에 디자인상의 문제가 없다고 생각합니다.
질문에 대한 답변
사용할 수 있습니다.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);
이 질문은 조금 오래된 질문이지만, 처음 방문하시는 분들은createMock
method(이전의 이름)createTestDouble
v5.4.0에서 도입되었습니다).
$mock = $this->createMock($className);
아래 코드에서 알 수 있듯이PHPUnitFrameworkTestCase
클래스(내)phpunit/src/framework/TestCase.php
)는 원래 컨스트럭터를 호출하지 않고 기본적으로 모의 객체를 만듭니다.
/** PHPUnitFrameworkTestCase::createMock method */ protected function createMock(string $originalClassName): MockObject {
return $this->getMockBuilder($originalClassName)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->disallowMockingUnknownTypes()
->getMock(); }
부록으로 첨부하고 싶었습니다.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에는 그들이 사용하지 않는 새로운 옵션이 있습니다.
Reflection Class:: new Instance Without Constructor
사용할 수 없었기 때문에 클래스를 수동으로 반영하고 생성자를 호출해야 했습니다.
$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);
주의:functionCallFromConstruct
이protected
, 특히 를 사용해야 합니다.setMethods()
따라서 보호된 방법이 조롱당하게 됩니다.예:
$mock->setMethods(array('functionCallFromConstructor'));
setMethods()
먼저 호출해야 합니다.expect()
제가 개인적으로 이 체인을 매고 나서disableOriginalConstructor()
그 전에getMock()
.
또는 기본 생성자가 호출되지 않도록 getMock에 매개 변수를 추가할 수도 있습니다.
$mock = $this->getMock(class_name, methods = array(), args = array(),
mockClassName = '', callOriginalConstructor = FALSE);
그래도 dave1010의 답변이 더 좋은 것 같습니다.완전성을 위해서입니다.