PHPUnit Mock 多种不同的方法
Posted
技术标签:
【中文标题】PHPUnit Mock 多种不同的方法【英文标题】:PHPUnit Mock multiple different methods 【发布时间】:2015-10-27 05:45:12 【问题描述】:我是单元测试的新手,我正在试验 phpUnit 框架。
我有一个调用另外两个函数的函数:
class Dummy
public function dummyFunction()
$this->anotherDummyFunction();
.....
$this->yetAnotherDummyFunction();
public function anotherDummyFunction()
.....
public function yetAnotherDummyFunction()
.....
我想测试调用 dummyFunction() 时是否调用了这两个函数。
这里是测试类:
class TestDummyClass
public function testDummyFunction()
$dummyClassMock = $this->getMockBuilder('Dummy')
->setMethods( array( 'anotherDummyFunction','yetAnotherDummyFunction' ) )
->getMock();
$dummyClassMock->expects($this->once())
->method( 'anotherDummyFunction' );
$dummyClassMock->expects($this->once())
->method( 'yetAnotherDummyFunction' );
$dummyClassMock->dummyFunction();
现在我注意到,如果我以这种方式模拟 Dummy 类,结果是
方法名称等于 anotherDummyFunction 的预期失败 当被调用 1 次时。方法预计会被调用 1 次, 实际调用了 0 次。
但是如果我以这种方式设置 Mock 对象
$dummyClassMock = $this->getMockBuilder('Dummy')
->setMethods( array( 'anotherDummyFunction' ) )
->getMock();
测试通过。最后,如果我用 setMethods(null) 设置 mock 对象,测试又失败了
似乎我可以传递一个只有一个元素的数组,我想要检查的方法是否被调用。但我在这里看到:https://jtreminio.com/2013/03/unit-testing-tutorial-part-5-mock-methods-and-overriding-constructors/ setMethods 用于注入传递的方法的返回值,所以这不会对调用本身产生影响,除非我将 dummyFunction 放在 setMethods 中(在这种情况下,函数将返回null而不调用其他两个方法,这样是的,测试必须失败)
我做错了什么?我已经看到在 setMethods() 中有多个方法的代码片段......为什么如果我将这些方法放在 setMethods 中,测试会失败?
谢谢
【问题讨论】:
嗯,这很奇怪,但它对我有用。顺便问一下,你确定TestDummyClass
是继承自PHPUnit_Framework_TestCase
吗?你使用的是什么版本的phpunit?我的是4.6.9
。
谢谢 Alexander,是的,它继承自 PHPUnit_Framework_TestCase
,实际上是其他测试通过。我正在使用 text sublime 和用于 text sublime 的 PHPUnit 插件。 phpUnit 的版本是 4.6.6 但我不认为我可以使用新版本,因为插件。稍后我将尝试使用另一个带有新版本 phpUnit 的编辑器
【参考方案1】:
您使用的是$this->once()
,这意味着只有在该方法只被调用一次的情况下才能通过测试——在每个使用模拟的测试用例中!
您可能想要的是$this->any()
,它不需要每次都调用该方法。
【讨论】:
你的意思是“只有当方法被调用一次时测试才能通过——在每个使用模拟的测试用例中”?那,如果我有两个测试方法,必须调用函数,否则测试不会通过?如果我测试$this->any()
,即使根本没有调用该方法,测试也不会通过吗? (0 个调用通过?)我已将模拟声明为方法变量,因此无法从其他测试方法访问它
是的,如果您有两个test*
方法,则在使用$this->once()
时,每个模拟方法必须只调用一次(不多也不少)。如果根本不调用该方法,则测试确实通过了。你确定这些方法实际上是调用的吗?如果您只在生产代码中的dummyFunction
内部调用它们,则模拟dummyFunction
不会调用它们。
为什么他们不被模拟dummyFunction
调用?它是一个模拟,而不是一个存根......一个模拟将做真正的方法所做的......一个存根只返回 null 或您设置的任何内容。所以如果真正的方法调用另外两个方法,mock 会有相同的行为,方法必须被调用并且测试必须通过以上是关于PHPUnit Mock 多种不同的方法的主要内容,如果未能解决你的问题,请参考以下文章
PHPUnit “模拟方法不存在。”当使用 $mock->expects($this->at(...))
使用 PHPUnit 对具有多种用户类型的网站进行单元测试的最佳方法