gpt4 book ai didi

php - 使用phpunit模拟抽象类中的具体方法

转载 作者:IT王子 更新时间:2023-10-28 23:53:46 25 4
gpt4 key购买 nike

有什么好的方法可以使用 PHPUnit 模拟抽象类中的具体方法吗?

到目前为止我发现的是:

  • expects()->will() 使用抽象方法可以正常工作
  • 它不适用于具体方法。改为运行原始方法。
  • 使用 mockbuilder 并将所有抽象方法和具体方法提供给 setMethods() 是可行的。但是,它要求您指定所有抽象方法,使测试变得脆弱且过于冗长。
  • MockBuilder::getMockForAbstractClass() 忽略 setMethod()。


以下是一些单元测试,用于说明以上几点:

abstract class AbstractClass {
public function concreteMethod() {
return $this->abstractMethod();
}

public abstract function abstractMethod();
}


class AbstractClassTest extends PHPUnit_Framework_TestCase {
/**
* This works for abstract methods.
*/
public function testAbstractMethod() {
$stub = $this->getMockForAbstractClass('AbstractClass');
$stub->expects($this->any())
->method('abstractMethod')
->will($this->returnValue(2));

$this->assertSame(2, $stub->concreteMethod()); // Succeeds
}

/**
* Ideally, I would like this to work for concrete methods too.
*/
public function testConcreteMethod() {
$stub = $this->getMockForAbstractClass('AbstractClass');
$stub->expects($this->any())
->method('concreteMethod')
->will($this->returnValue(2));

$this->assertSame(2, $stub->concreteMethod()); // Fails, concreteMethod returns NULL
}

/**
* One way to mock the concrete method, is to use the mock builder,
* and set the methods to mock.
*
* The downside of doing it this way, is that all abstract methods
* must be specified in the setMethods() call. If you add a new abstract
* method, all your existing unit tests will fail.
*/
public function testConcreteMethod__mockBuilder_getMock() {
$stub = $this->getMockBuilder('AbstractClass')
->setMethods(array('concreteMethod', 'abstractMethod'))
->getMock();
$stub->expects($this->any())
->method('concreteMethod')
->will($this->returnValue(2));

$this->assertSame(2, $stub->concreteMethod()); // Succeeds
}

/**
* Similar to above, but using getMockForAbstractClass().
* Apparently, setMethods() is ignored by getMockForAbstractClass()
*/
public function testConcreteMethod__mockBuilder_getMockForAbstractClass() {
$stub = $this->getMockBuilder('AbstractClass')
->setMethods(array('concreteMethod'))
->getMockForAbstractClass();
$stub->expects($this->any())
->method('concreteMethod')
->will($this->returnValue(2));

$this->assertSame(2, $stub->concreteMethod()); // Fails, concreteMethod returns NULL
}
}

最佳答案

2 年前有一个 Pull Request,但该信息从未添加到文档中:https://github.com/sebastianbergmann/phpunit-mock-objects/pull/49

您可以在 getMockForAbstractClass() 的参数 7 中的数组中传递您的具体方法。

查看代码:https://github.com/andreaswolf/phpunit-mock-objects/blob/30ee7452caaa09c46421379861b4128ef7d95e2f/PHPUnit/Framework/MockObject/Generator.php#L225

关于php - 使用phpunit模拟抽象类中的具体方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8040296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com