如何在 PHP 中对具有依赖项的方法进行单元测试? [英] How to unit test a method with dependencies in PHP?

查看:29
本文介绍了如何在 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 替换它,以便单元测试在没有真正访问数据库的情况下工作.

结论

  • 如果你有像上面那样的代码:重构它并使用依赖注入.
  • 如果您有遗留代码或只是不想重构,请尝试以下解决方案:http://sebastian-bergmann.de/archives/885-Stubbing-Hard-Coded-Dependencies.html

    解决方案

    With PHPUnit 你可以做

     $class = $this->getMockClass('Client',/* 要模拟的类名 */array('getClient')/* 模拟方法列表 */);$class::staticExpects($this->any())->方法('getClient')->will($this->returnValue('foo'));

    通常,您希望避免使用静态方法:

    <小时>

    更新后编辑

    PHPUnit 还可以存根硬编码的依赖项.见

    但是,由于您现在已经注意到测试静态和硬编码依赖项是一个痛苦的过程,我建议您使用注入到 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

  • If you have code like the one presented: refactor it and use Dependency Injection.
  • If you have legacy code or just don't want to refactor try this solution: http://sebastian-bergmann.de/archives/885-Stubbing-Hard-Coded-Dependencies.html

    解决方案

    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:


    EDIT after update

    PHPUnit can also stub hardcoded dependencies. See

    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屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆