對文件系統(tǒng)進(jìn)行模仿

2018-02-24 15:42 更新

對文件系統(tǒng)進(jìn)行模仿

vfsStream 是對虛擬文件系統(tǒng)流包覆器(stream wrapper),可以用于模仿真實(shí)文件系統(tǒng),在單元測試中可能會有所助益。

如果使用 Composer 來管理項(xiàng)目的依賴關(guān)系,那么只需簡單的在項(xiàng)目的 composer.json 文件中加一條對 mikey179/vfsStream 的依賴關(guān)系即可。以下是一個最小化的 composer.json文件例子,只定義了一條對 PHPUnit 4.6 與 vfsStream 的開發(fā)時(development-time)依賴:

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

Example?9.21, “一個與文件系統(tǒng)交互的類”展示了一個與文件系統(tǒng)交互的類。

Example?9.21.?一個與文件系統(tǒng)交互的類

<?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 這樣的虛擬文件系統(tǒng),就無法在隔離外部影響的情況下對 setDirectory() 方法進(jìn)行測試(參見 Example?9.22, “對一個與文件系統(tǒng)交互的類進(jìn)行測試”)。

Example?9.22.?對一個與文件系統(tǒng)交互的類進(jìn)行測試

<?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');
        }
    }
}
?>

上面的方法有幾個缺點(diǎn):

  • 和任何其他外部資源一樣,文件系統(tǒng)可能會間歇性的出現(xiàn)一些問題,這使得和它交互的測試變得不可靠。

  • setUp()tearDown() 方法中,必須確保這個目錄在測試前和測試后均不存在。

  • 如果測試在 tearDown() 方法被調(diào)用之前就終止了,這個目錄就會遺留在文件系統(tǒng)中。

Example?9.23, “在對與文件系統(tǒng)交互的類進(jìn)行的測試中模仿文件系統(tǒng)”展示了如何在對與文件系統(tǒng)交互的類進(jìn)行的測試中使用 vfsStream 來模仿文件系統(tǒng)。

Example?9.23.?在對與文件系統(tǒng)交互的類進(jìn)行的測試中模仿文件系統(tǒng)

<?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'));
    }
}
?>

這有幾個優(yōu)點(diǎn):

  • 測試本身更加簡潔。

  • vfsStream 讓開發(fā)者能夠完全控制被測代碼所處的文件系統(tǒng)環(huán)境。

  • 由于文件系統(tǒng)操作不再對真實(shí)文件系統(tǒng)進(jìn)行操作,tearDown() 方法中的清理操作不再需要了。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號