需要关于在类中对复杂方法进行PHP单元测试的建议


Need advice on doing PHP unit test on complex methods within a class

我是单元测试的初学者,并且很难测试算法(在实际实现中可由cron执行),该算法在PHP类中具有没有参数的函数以及依赖于数据源的其他类,例如:

class Mailing_System_Algo {     
    function __construct()
    {
        //Run the mailing system method    
        $this->execute_mailing_system();
    }
    function execute_mailing_system()
    {           
        $Class_Data_Source = new Data_Source;
        $groups = $Class_Data_Source->get_groups();
        //Proceed only if groups are defined
        if (!(empty($groups))) {
            //rest of the algo codes here-very long and lots of loops and if statements
        }
    }   
}

我想把算法函数当作一个黑盒,所以当我做测试时,我不会改变他们代码上的任何东西。但是,如果execute_mailing_system将在类实例化后立即运行,那么如何通过向它们提供输入来开始测试它们呢?

假设我想检查算法是否会在有或没有组的情况下执行,我如何在我的单元测试代码中为$groups提供输入?

我的测试用例是这样的:

class WP_Test_Mailing_System_Algo extends WP_UnitTestCase {
/**
 * Run a simple test to ensure that the tests are running
 */

function test_tests() {
            //no problem here
    $this->assertTrue( true );
}
function test_if_algo_wont_run_if_no_groups_provided {
            //Instantiate, but won't this algo run the construct function rightaway?
    $Mailing_System_Algo = new Mailing_System_Algo;
            //rest of the test codes here
            //how can I access or do detailed testing of execute_mailing_system() function and test if it won't run if groups are null or empty.
            //The function does not have any arguments
}

}

当然还有很多测试我要写,但我目前卡在这一个。这是我需要执行的第一个测试。但我有一个问题,如何开始这样做。我相信一旦我掌握了正确的技术,剩下的测试就会很简单了。我将非常感谢您的任何输入和帮助,谢谢。

代码中有两个缺陷会妨碍测试:

  1. Constructor does Real Work
  2. <
  3. 硬编码依赖/gh>

您可以通过将类更改为

来改进这一点
class Mailing_System_Algo 
{     
    public function __construct()
    {
        // constructors should not do work
    }
    public function execute_mailing_system(Data_Source $Class_Data_Source)
    {           
        $groups = $Class_Data_Source->get_groups();
        //Proceed only if groups are defined
        if (!(empty($groups))) {
            //rest of the algo codes here-very long and lots of loops and if statements
        }
    }   
}

这是一种方法,您可以用Mock或Stub替换Data_Source,返回定义的测试值。

如果这不是一个选项,请查看Test Helper扩展:

  • https://github.com/sebastianbergmann/php-test-helpers¹

特别地,看一下set_new_overload(),它可以用来注册一个回调,当执行new操作符时自动调用。


¹Test-Helper扩展被https://github.com/krakjoe/uopz

取代