这是我正在使用的代码的简化版本:
class FirstClass{
public $theSecondObject;
function exampleForTesting(){
$this->theSecondObject = SecondClass::getInstance();
return $this->theSecondObject->getRandomSentence();
}
}
class SecondClass{
private static $instance = null;
private $randomSentence;
private function __construct($someString){
$this->randomSentence = $someString;
}
public static function getInstance(){
if(self::instance === null){
self::$instance = new SecondClass('Just a random sentence.');
}
return self::$instance;
}
public function getRandomSentence(){
return $this->randomSentence;
}
}
class FirstClassTestCase {
public function startTest($method){
$this->firstClassObject = new FirstClass();
}
public function testExampleForTesting(){
$this->firstClassObject->theSecondObject = $this->getMock('SecondClass', ['getRandomSentence']);
$this->firstClassObject->theSecondObject->expects($this->any()
->method('getRandomSentence')
->will($this->returnValue('A test unexpected sentence.'));
$expected = 'Just a random sentence.';
$actual = $this->firstClassObject->exampleForTesting();
$this->assertNotEquals($expected, $actual);
}
}
我有一个带有函数exampleForTesting()的FirstClass,该函数调用SecondClass()函数,我想模拟该函数的返回值以进行测试。但是,SecondClass()构造函数是私有的,运行测试结果将引发错误:
Fatal Error Error: Call to private SecondClass::__construct()
这似乎是由于通过getInstance()函数实例化SecondClass对象的独特方式。有没有解决这个问题的潜在方法,而不必更改SecondClass构造函数? SecondClass实际上是我的应用程序中的一个外部调用,因此我无法更改它。
我还注意到,即使我试图将构造函数设置为public以查看测试是否会通过,它实际上也会失败,因为$ actual变量会生成与$ expected相同的值。我是否错误地执行了返回值模拟?
答案 0 :(得分:1)
一种选择是更改您的实现并使用名为dependency injection的东西。
@NgModule({
declarations: [ProductPageComponent
..
],
entryComponents: [ProductPageComponent],
imports: [
..
],
providers: [...],
bootstrap: [AppComponent]
})
这样,您可以在测试中轻松模拟class FirstClass
{
public function __construct(SecondClass $secondClass)
{
//...
}
}
并将其作为参数传递给SecondClass
。
FirstClass
有时,包装不属于您的类也很有意义,因为这样做通常会给您带来更大的灵活性。