Phpunit 基于无脂肪框架的单元测试

Phpunit 基于无脂肪框架的单元测试,phpunit,fat-free-framework,Phpunit,Fat Free Framework,有没有一种方法可以使用PHPUnit,其中我有一个测试文件夹,里面有indexTest.php,可以测试index.php文件中的路由 《无脂肪指南》给出了模拟路由请求和帖子的代码片段。只有当我在测试文件中直接生成包含任何功能的路由时,我才能使这样的测试正常工作 我想要的是用令牌模拟一个路由,允许它从index.php中的一个路由运行,并通过控制器和测试应该通过运行路由设置的f3变量 <?php class indexTest extends \PHPUnit_Framework_Tes

有没有一种方法可以使用PHPUnit,其中我有一个测试文件夹,里面有indexTest.php,可以测试index.php文件中的路由

《无脂肪指南》给出了模拟路由请求和帖子的代码片段。只有当我在测试文件中直接生成包含任何功能的路由时,我才能使这样的测试正常工作

我想要的是用令牌模拟一个路由,允许它从index.php中的一个路由运行,并通过控制器和测试应该通过运行路由设置的f3变量

<?php

class indexTest extends \PHPUnit_Framework_TestCase
{
    public function test()
    {
        $f3 = Base::instance();
// Don't write to STDOUT
        $f3->set('QUIET', true);
        $f3->route('GET /path', function(){ echo 'TEXT'; });

        $this->assertNull($f3->mock('GET /path'));
        $this->assertSame('TEXT', $f3->get('RESPONSE'));

        $f3->route('GET /verify/@answer/@value',
            function($f3, $params){
                $errors = array();

                $answer = $params['answer'];
                $value = $params['value'];

                $prefix = substr($answer, 0, 3);  //pre, ans, pos
                $id = (int)substr($answer, 3);      //question id number (1, 2, 3, 4)
//$value is the input value from user

                $result = check_id($prefix, $id, $value);

                if($result !== true){
                    $errors[] = $result;
                }
                $f3->set('errors', $errors);
                return $errors;
            });

        function check_id($prefix, $id, $value)
        {
            if($prefix == 'pre' || $prefix == 'pos'){

                if($value <= 0 || $value > 180 || $value === NULL){
                    echo 'The input value of ' . $prefix . $id . ' question was out of bounds';
                    return 'The input value of ' . $prefix . $id . ' question was out of bounds';
                }else{
                    return true;
                }

            }else if($prefix == 'ans'){

                if($value < 0 || $value > 10 || $value === NULL){
                    echo 'The value of quiz ans' + $id + ' was out of bounds';
                    return 'The value of quiz ans' + $id + ' was out of bounds';
                }else{
                    return true;
                }

            }else {
                return 'The prefix does not match';
            }
        }

        $this->assertNotNull($f3->mock('GET /verify/ans1/8'));
        $this->assertEmpty($f3->get('RESPONSE')[0]);

        $this->assertNotNull($f3->mock('GET /verify/dsk4/6'));
        $this->assertSame('6', $f3->get('PARAMS.value'));
        $this->assertSame('dsk4', $f3->get('PARAMS.answer'));
        $this->assertEmpty($f3->get('RESPONSE')[0]);

        $this->assertNotNull($f3->mock('GET /verify/pre4/250'));
        $this->assertSame('The input value of pre4 question was out of bounds', $f3->get('errors')[0]);
        $this->assertNotSame('pre4', $f3->get('PARAMS.answer'));

        $f3->set('QUIET',FALSE); // allow test results to be shown later

        $f3->clear('ERROR');  // clear any errors
    }
}
简短回答
  • 将控制器代码与引导和路由代码分开

  • 在您的环境中重新使用路由配置,例如网站、CLI和测试环境

  • 在测试中使用
    Base->mock()
    模拟先前定义的路由

  • 不要在测试环境中执行
    Base->run()


长话短说 我计划花很长时间写一篇关于测试F3路线的文章,但由于时间不够,我将在这里给出一些观点:

  • 创建定义路由的可重用文件(例如
    routes.php
    文件或带有路由定义的
    INI
    文件)

  • 在运行测试代码之前加载路由。使用PHPUnit的自定义引导文件(
    --bootstrap
    或在PHPUnit的配置中使用相应的指令)可以很容易地实现这一点

  • 编写PHPUnit测试

  • 例子 以下示例是my的一个改编:

    bootstrap-website.php

    <?php
    
    $f3 = Base::instance();
    
    require 'bootstrap-shared.php';
    
    // [Custom rules only for the website here]
    
    require 'routes.php';
    
    $f3->run();
    
    <?php
    
    $f3 = Base::instance();
    
    require 'bootstrap-shared.php';
    
    // [Custom rules only for testing environment here]
    
    $f3->set('QUIET', true);
    $f3->set('APP.TEST', true);
    
    require 'routes.php';
    
    <?php
    
    /**
     * @var $f3 Base
     */
    
    $f3->route('GET /path', function(){ echo 'TEXT'; });
    
    class ExampleTest extends PHPUnit_Framework_TestCase {
        public function test() {
            // Could also be provided by a custom base TestCase.
            $f3 = Base::instance();
    
            $this->assertNull($f3->mock('GET /path'));
            $this->assertSame('TEXT', $f3->get('RESPONSE'));
        }
    }
    
    一些注意事项:

    • bootstrap test.php
      是PHPUnit的自定义引导文件

    • bootstrap-website.php
      是网站的引导文件

    • bootstrap shared.php
      包含所有环境共享的信息。该文件可能包含路由信息。我在示例中分离了路由信息:
      routes.php

    • ExampleTest.php
      是一种常规的PHPUnit测试

    • $f3->set('QUIET',true)代码段应添加到自定义引导文件中。引入一个显示应用程序正在测试模式下运行的变量也是一个好主意,例如
      $f3->set('APP.test',true)

    • F3不会在测试/模拟之间清理变量。您可以在运行测试之前存储原始状态,然后在PHPUnit的
      setUp()
      方法中恢复该状态

    • 除了呈现页面之外,仅收集应可用于呈现的数据也足够了。在这种情况下,使用视图中引入的
      APP.TEST
      变量跳过渲染

    以后答案更新的注意事项

    • ini\u集('error\u log','./phpunit/error.log')
    • $f3->set('ONERROR',function(){})