PHPUnit的getMock($classname, $mockmethods)
根据给定的类名创建一个新对象,让我更改/测试指定方法的行为。
我渴望一些不同的东西;它正在改变现有对象方法的行为-无需构造新对象。
那可能吗?如果是,怎么办?
考虑问题时,我得出的结论是,可以通过序列化对象,更改序列化的字符串以使对象成为扩展旧类以及模拟方法的新类的实例来实现。
我想要一些代码-也许某处已经有这样的代码。
虽然当然可以再次创建要模拟的对象,但是在我的测试中这样做太复杂了。因此,如果我真的不是真的必须这样做,我不想这样做。这是一个TYPO3 TSFE实例,并且在引导过程中对其进行一次设置已经足够困难了。
最佳答案
让我首先说:欢迎来到单元测试的阴暗面。
含义:您通常不想这样做,但是正如您所解释的,您似乎拥有一个有效的用例。
运行套件
与更改应用程序体系结构相比,您可以轻松地做,不是琐碎的事,而是容易的事,是通过使用runkit快速更改类行为
runkit_method_rename(
get_class($object), 'methodToMock', 'methodToMock_old'
);
runkit_method_add(
get_class($object), 'methodToMock', '$param1, $param2', 'return 7;'
);
runkit::method_add在测试完method_remove之后,再次进行重命名。我不知道有什么框架/组件可以帮助您实现这一目标,但是用
UglyTestsBaseTest extends PHPUnit_Framework_TestCase
自己实现的框架并不多。出色地...
如果您只能访问该对象的引用(例如:
$x
中的$x = new Foo();
),我不知道该说什么:$ x,您现在是SomethingElse
类型,所有指向该对象的其他变量都应也改变。我假设您已经知道testing your privates之类的东西,但这对您没有帮助,因为您无法控制the objects life cycle。
php测试助手扩展
在这里可能还对您有所帮助的是:使用Stubbing Hard-Coded Dependencies的php-test-helpers extension,它允许您对进行拦截对象创建之类的操作。
这意味着,当您的应用程序调用
$x = new Something();
时,您可以破解PHP使其成为$x
,然后包含YourSpecialCraftedSomething
的实例。您可以使用PHPUnit Mocking API创建该分类,也可以自己编写。
据我所知,这些是您的选择。如果值得去那里(或者只是为该项目编写集成/ Selenium 测试),那么您就必须自己解决问题,因为这在很大程度上取决于您的情况。