Mocking concrete method in abstract class using phpunit(使用phpunit在抽象类中模拟具体方法)
问题描述
有没有什么好的方法可以使用 PHPUnit 模拟抽象类中的具体方法?
Are there any good ways to mock concrete methods in abstract classes using PHPUnit?
到目前为止我发现的是:
- expects()->will() 使用抽象方法可以正常工作
- 它不适用于具体方法.而是运行原始方法.
- 使用 mockbuilder 并将所有抽象方法和具体方法提供给 setMethods() 有效.但是,它需要您指定所有抽象方法,这使得测试变得脆弱且过于冗长.
- MockBuilder::getMockForAbstractClass() 忽略 setMethod().
以下是一些对上述几点进行示例的单元测试:
Here are some unit tests examplifying the above points:
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
There was a Pull Request for this 2 years ago, but the information never been added in the documentation : https://github.com/sebastianbergmann/phpunit-mock-objects/pull/49
您可以在 getMockForAbstractClass() 的参数 7 中的数组中传递具体方法.
You can pass your concrete method in an array in argument 7 of getMockForAbstractClass().
查看代码:https://github.com/andreaswolf/phpunit-mock-objects/blob/30ee7452caaa09c46421379861b4128ef7d95e2f/PHPUnit/Framework/MockObject/Generator.php#L225
这篇关于使用phpunit在抽象类中模拟具体方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用phpunit在抽象类中模拟具体方法
基础教程推荐
- Libpuzzle 索引数百万张图片? 2022-01-01
- 在 PHP 中强制下载文件 - 在 Joomla 框架内 2022-01-01
- 如何在 PHP 中的请求之间持久化对象 2022-01-01
- mysqli_insert_id 是否有可能在高流量应用程序中返回 2021-01-01
- 通过 PHP SoapClient 请求发送原始 XML 2021-01-01
- 超薄框架REST服务两次获得输出 2022-01-01
- XAMPP 服务器不加载 CSS 文件 2022-01-01
- 在 Woocommerce 中根据运输方式和付款方式添加费用 2021-01-01
- WooCommerce 中选定产品类别的自定义产品价格后缀 2021-01-01
- 在多维数组中查找最大值 2021-01-01