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

时间:2013-03-19 06:40:23

标签: php unit-testing phpunit

我是单元测试的初学者,并且很难测试算法(在实际实现中可由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立即运行,我怎么能通过输入它们来开始测试它们呢?

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

这就是我的测试用例的样子:

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 个答案:

答案 0 :(得分:2)

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

  1. Constructor does Real Work
  2. Hard-Coded Dependencies
  3. 您可以通过将班级更改为

    来改善这一点
    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
            }
        }   
    }
    

    这样,您可以将Data_Source替换为Mock or Stub,并返回已定义的测试值。

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

    特别要看一下set_new_overload(),它可以用来注册一个在执行new运算符时自动调用的回调。


    the Test-Helper extension is superseded

    ¹https://github.com/krakjoe/uopz