如何在 PHP 中对具有依赖项的方法进行单元测试? [英] How to unit test a method with dependencies in PHP?
问题描述
我有一个包含一些逻辑的方法,但我不确定如何对其进行单元测试.因为它是此特定方法的单元测试,所以它应该在不连接到数据库的情况下运行.我阅读了关于存根和模型的文章,但我找不到将它们应用于这种情况的方法.
我想强制 Client:GetClient 返回具有正确属性的客户端对象,以便我可以测试每个逻辑分支.
<前><代码>类客户端类型{函数 GetClientType($id) {$objClient = Client::GetClient($id);如果($objClient->返回== 1){return '返回';}别的 {返回正常";}}这是我想到的测试
<前><代码>类 ResourceTest 扩展 PHPUnit_Framework_TestCase {函数 testGetClientType() {$objClientType = new ClientType();$this->assertTrue($objClientType->GetClientType(100), 'normal');}}问题是依赖$objClient = Client::GetClient($id);GetClient 将从数据库中拉出一个客户端,但我需要用 Stub 替换它,以便单元测试在没有真正访问数据库的情况下工作.
结论
With PHPUnit 你可以做
$class = $this->getMockClass('Client',/* 要模拟的类名 */array('getClient')/* 模拟方法列表 */);$class::staticExpects($this->any())->方法('getClient')->will($this->returnValue('foo'));
通常,您希望避免使用静态方法:
- http://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html
- https://kore-nordmann.de/blog/0103_static_thinked_harmful.html
更新后编辑
PHPUnit 还可以存根硬编码的依赖项.见
- Stubing Hard-Coded Dependencies 作者:Sebastian Bergmann
但是,由于您现在已经注意到测试静态和硬编码依赖项是一个痛苦的过程,我建议您使用注入到 ClientType 中的真实对象来删除硬编码依赖项和静态调用.
另一种选择是使用 http://antecedent.github.io/patchwork(不是隶属于它),其中
<块引用>是一个 PHP 库,可以重新定义用户定义的函数和方法在运行时,在纯 PHP 5.3 代码中松散地复制功能 runkit_function_redefine,其中,它使您能够用测试替身替换静态和私有方法.
I have a method with some logic in it and I'm not sure how to unit test it. Because it's a unit test for this specific method it should run without connecting to the database. I read about stubs and mockups but I can't find a way to apply them to this situation.
I would like to force the Client:GetClient to return the client object with the right properties so I can test each logic branch.
class ClientType {
function GetClientType($id) {
$objClient = Client::GetClient($id);
if ($objClient->Returning == 1) {
return 'returning';
}
else {
return 'normal';
}
}
This is the test I had in mind
class ResourceTest extends PHPUnit_Framework_TestCase {
function testGetClientType() {
$objClientType = new ClientType();
$this->assertTrue($objClientType->GetClientType(100), 'normal');
}
}
The problem is the dependency $objClient = Client::GetClient($id); The GetClient will pull a client from database but I need to replace this with a Stub so the unit tests work without real access to the database.
Conclusion
With PHPUnit you can do
$class = $this->getMockClass(
'Client', /* name of class to mock */
array('getClient') /* list of methods to mock */
);
$class::staticExpects($this->any())
->method('getClient')
->will($this->returnValue('foo'));
In general, you want to avoid static methods though:
- http://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html
- https://kore-nordmann.de/blog/0103_static_considered_harmful.html
EDIT after update
PHPUnit can also stub hardcoded dependencies. See
- Stubbing Hard-Coded Dependencies by Sebastian Bergmann
However, since you already noticed by now that it is a Pain the Behind to test statics and hardcoded dependencies, I suggest you remove the hardcoded dependency and static call with a real object that you inject into your ClientType instead.
Another option would be to use http://antecedent.github.io/patchwork (not affiliated with it), which
is a PHP library that makes it possible to redefine user-defined functions and methods at runtime, loosely replicating the functionality runkit_function_redefine in pure PHP 5.3 code, which, among other things, enables you to replace static and private methods with test doubles.
这篇关于如何在 PHP 中对具有依赖项的方法进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!