douhuibo5635 2012-03-23 20:12
浏览 10
已采纳

模拟在PHP中使用静态方法创建的对象的函数?

I'm using an ORM and the way I get an object of the record is using FooModel::find(1). FooModel has a method I need to mock for testing. How can I do it? (Can't use the PHPUnit mock because that would give me a mocked FooModel that'll not correspond to the record with ID 1.)

Edit

Example:

class FooModel
{
    // ORM model that fetches record from the DB

    public function thisNeedsToBeMocked()
    {
        // some code here that depends on external factors so should be part of unit tests
    }
}

The way I get the record with ID 1 is:

$fooObject = FooModel::find(1);

I need to be able of mock the thisNeedsToBeMocked() of $fooObject that I have after I run the static method find().

  • 写回答

1条回答 默认 最新

  • doucang6739 2012-03-23 20:47
    关注

    You have hit on a classic unit testing problem. The class name you are using to call statically is part of the global namespace. That means there is no point in which you can insert a mock. This is no magic you can do here, to solve this problem you will have to make some code changes.

    There many ways to solve this and there are many fors and against each of them. I will give you a simple hacker solution. If you would like something different let me know and I will code up an example.

    I will also assume that you can't change the ORM from being static class based.

    Here is the hacker approach, which is a very bad way of doing things, so you know. Have a variable in your class that is the class name of the ORM class you need to use. This is PHP 5.3 code.

    Like so:

    <?php
    
    class Bar {
        public static $ormName = 'FooModel';
    
        public static function doStuff()
        {
            $className = self::$ormName;
            echo $className::find(1), "
    ";
        }
    }
    

    Then in your PHPUnit test create a mock. Get it's class name, set that class name on your test subject. Now your test subject will call your mock.

    There are so many ways to some this problem but some how you need a way to not use the class name directly.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容