codecamp

对文件系统进行模仿

对文件系统进行模仿

vfsStream 是对虚拟文件系统流包覆器(stream wrapper),可以用于模仿真实文件系统,在单元测试中可能会有所助益。

如果使用 Composer 来管理项目的依赖关系,那么只需简单的在项目的 composer.json 文件中加一条对 mikey179/vfsStream 的依赖关系即可。以下是一个最小化的 composer.json文件例子,只定义了一条对 PHPUnit 4.6 与 vfsStream 的开发时(development-time)依赖:

{
    "require-dev": {
        "phpunit/phpunit": "~4.6",
        "mikey179/vfsStream": "~1"
    }
}

Example 9.21, “一个与文件系统交互的类”展示了一个与文件系统交互的类。

Example 9.21. 一个与文件系统交互的类

<?php
class Example
{
    protected $id;
    protected $directory;

    public function __construct($id)
    {
        $this->id = $id;
    }

    public function setDirectory($directory)
    {
        $this->directory = $directory . DIRECTORY_SEPARATOR . $this->id;

        if (!file_exists($this->directory)) {
            mkdir($this->directory, 0700, TRUE);
        }
    }
}?>

如果不使用诸如 vfsStream 这样的虚拟文件系统,就无法在隔离外部影响的情况下对 setDirectory() 方法进行测试(参见 Example 9.22, “对一个与文件系统交互的类进行测试”)。

Example 9.22. 对一个与文件系统交互的类进行测试

<?php
require_once 'Example.php';

class ExampleTest extends PHPUnit_Framework_TestCase
{
    protected function setUp()
    {
        if (file_exists(dirname(__FILE__) . '/id')) {
            rmdir(dirname(__FILE__) . '/id');
        }
    }

    public function testDirectoryIsCreated()
    {
        $example = new Example('id');
        $this->assertFalse(file_exists(dirname(__FILE__) . '/id'));

        $example->setDirectory(dirname(__FILE__));
        $this->assertTrue(file_exists(dirname(__FILE__) . '/id'));
    }

    protected function tearDown()
    {
        if (file_exists(dirname(__FILE__) . '/id')) {
            rmdir(dirname(__FILE__) . '/id');
        }
    }
}
?>

上面的方法有几个缺点:

  • 和任何其他外部资源一样,文件系统可能会间歇性的出现一些问题,这使得和它交互的测试变得不可靠。

  • setUp()tearDown() 方法中,必须确保这个目录在测试前和测试后均不存在。

  • 如果测试在 tearDown() 方法被调用之前就终止了,这个目录就会遗留在文件系统中。

Example 9.23, “在对与文件系统交互的类进行的测试中模仿文件系统”展示了如何在对与文件系统交互的类进行的测试中使用 vfsStream 来模仿文件系统。

Example 9.23. 在对与文件系统交互的类进行的测试中模仿文件系统

<?php
require_once 'vfsStream/vfsStream.php';
require_once 'Example.php';

class ExampleTest extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
        vfsStreamWrapper::register();
        vfsStreamWrapper::setRoot(new vfsStreamDirectory('exampleDir'));
    }

    public function testDirectoryIsCreated()
    {
        $example = new Example('id');
        $this->assertFalse(vfsStreamWrapper::getRoot()->hasChild('id'));

        $example->setDirectory(vfsStream::url('exampleDir'));
        $this->assertTrue(vfsStreamWrapper::getRoot()->hasChild('id'));
    }
}
?>

这有几个优点:

  • 测试本身更加简洁。

  • vfsStream 让开发者能够完全控制被测代码所处的文件系统环境。

  • 由于文件系统操作不再对真实文件系统进行操作,tearDown() 方法中的清理操作不再需要了。

对 Web 服务(Web Services)进行上桩或模仿
在开发过程中
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

3. 命令行测试执行器

7. 未完成的测试与跳过的测试

12. 测试的其他用途

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }