在PHP单元中创建模拟对象

Mik*_*ike 9 php phpunit unit-testing mocking

我已经搜索过,但找不到我正在寻找的东西,手册在这方面没什么帮助.我对单元测试很新,所以不确定我是否在正确的轨道上.无论如何,问题.我有一节课:

<?php
    class testClass {
        public function doSomething($array_of_stuff) {
            return AnotherClass::returnRandomElement($array_of_stuff);
        }
    }
?>
Run Code Online (Sandbox Code Playgroud)

现在,显然我希望AnotherClass::returnRandomElement($array_of_stuff);每次都返回相同的东西.我的问题是,在我的单元测试中,我如何模拟这个对象?

我已经尝试添加AnotherClass到测试文件的顶部,但是当我想测试时,AnotherClass我得到"无法重新声明类"错误.

我想我理解工厂类,但我不确定在这种情况下我将如何应用它.我是否需要编写一个完全独立的AnotherClass类,其中包含测试数据,然后使用Factory类加载而不是真正的AnotherClass?或者使用工厂模式只是一个红鲱鱼.

我试过这个:

    $RedirectUtils_stub = $this->getMockForAbstractClass('RedirectUtils');

    $o1 = new stdClass();
    $o1->id = 2;
    $o1->test_id = 2;
    $o1->weight = 60;
    $o1->data = "http://www.google.com/?ffdfd=fdfdfdfd?route=1";
    $RedirectUtils_stub->expects($this->any())
         ->method('chooseRandomRoot')
         ->will($this->returnValue($o1));
    $RedirectUtils_stub->expects($this->any())
         ->method('decodeQueryString')
         ->will($this->returnValue(array()));
Run Code Online (Sandbox Code Playgroud)

在setUp()函数中,这些存根被忽略,我无法弄清楚它是我做错了什么,还是我访问AnotherClass方法的方式.

救命!这让我疯了.

Tyl*_*ter 6

使用单元测试,您希望创建包含静态数据的"测试"类,然后将这些类传递到测试类中.这将从测试中删除变量.

class Factory{
    function build()
    {
        $reader = new reader();
        $test = new test($reader);
        // ..... do stuff
    }

}

class Factory{
    function build()
    {
        $reader = new reader_mock();
        $test = new test($reader);
        // ..... do stuff
    }

}
class reader_mock
{
    function doStuff()
    {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

因为您正在使用静态类,所以必须AnotherClass从程序中删除,然后重新创建它,使其仅包含返回测试数据的函数.通常,您不希望实际从程序中删除类,这就是您像上面的示例一样传递类的原因.