Introduction to vfsstream

Source: Internet
Author: User
  1. What is vfsstream?

The project homepage of vfsstream on Google Code has the following introduction: vfsstream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. it can be used with any unit test framework, like phpunit or simpletest.
Vfsstream is a Virtual File System Based on stream warpper. It can simulate real file systems in unit tests.

Stream wrapper in PHP allows users to implement custom protocols, protocol processors, and streams. Once a custom protocol is created, you can use functions such as mkdir (), fopen (), and fread () to process the stream based on this protocol. If you want to create a custom protocol that meets certain conditions, you can refer to the PHP manual for more information.

 

  1. Why use vfsstream?

Vfsstream can be used to simulate a file system in a unit test to decouple the test code from the real file system. Using mkdir () and other methods on vfsstream will not generate any junk files on the disk, and all operations will be performed in the memory. A common example is:

Class to be tested-check whether a folder exists on the disk. If it does not exist, it is created.

<?phpclass Example {public function __construct($id) {$this->id = $id;}public function setDirectory($dir) {$this->dir = $dir . '/' . $this->id;if (file_exists($this->dir) === false) {mkdir($this->dir, 0700, true);}}}

The traditional test cases are as follows:

<?php class ExampleTest extends PHPUnit_Framework_TestCase {$DIR = dirname(__FILE__);public function setUp() {if (file_exists($DIR . '/id')) {rmdir($DIR . '/id');}}public function tearDown() {if (file_exists($DIR . '/id')) {rmdir($DIR . '/id');}}public function testDirectoryIsCreated() {$example = new Example('id');$this->assertFalse(file_exists($DIR . '/id'));$example->setDirectory($DIR);$this->assertTrue(file_exists($DIR . '/id'));}}

A major problem with traditional test cases is that "junk files" will be created on the file system during the test case running. Therefore, you need to clean up the files in the setup () and teardown () methods.

Test Cases Using vfsstream:

<?phpclass ExampleTest extends PHPUnit_Framework_TestCase {public function setUp() {vfsStreamWrapper::register();$root = new vfsStreamDirectory('aDir');vfsStreamWrapper::setRoot($root);}public function testDirectoryIsCreated() {$url = vfsStream::url('aDir/id');$example = new Example('id');$this->assertFalse(file_exists($url));$example->setDirectory(vfsStream::url('aDir'));$this->assertTrue(file_exists($url));}}

It can be found that after vfsstream is used, no cleanup is required in the setup () or teardown () method. Because all vfsstream operations are performed in the memory.

  1. How can I use vfsstream?

I found this interesting and useful stuff when reading the phpunit manual. In the restiny test case, vfsstream is used to create a configuration file in the file system for configloader to read. The Code is as follows:

Configloader class:

<? PHP/*** configure the loader ***/class configloader {public function loadconfig ($ configfilename, $ configdirectorypath = '') {If (empty ($ configdirectorypath )) {$ configdirectorypath = app_path. directory_separator. 'config';} $ configfilepath = $ configdirectorypath. directory_separator. $ configfilename. '. php'; If (! File_exists ($ configfilepath) {Throw new restinyfilenotfoundexception ($ configfilename. 'config file not found ', 0);} return require_once $ configfilepath ;}}

Configloader searches for the configuration file named $ configfilename in the path where $ configdirectorypath is executed. If not found, an exception is thrown.

The configloader test case is as follows:

<? PHP/*** test case-configure the loader **/require_once dirname (_ file __)). directory_separator. 'testbootstrap. PHP '; require_once dirname (_ file __). '/http://www.cnblogs.com/core/configloader.php'?require_once' vfsstream/vfsstreamdirectory. PHP '; require_once' vfsstream/vfsstreamwrapper. PHP '; require_once' vfsstream/vfsstream. PHP ';/*** test class for config. * generated by phpunit on at 04:05:20. */Class configloadertest extends phpunit_framework_testcase {private $ _ rootconfigdir = 'configdir'; private $ _ configdir = 'resources'; private $ _ configfilename = 'resources '; private $ _ configfile = 'resources. php'; protected function setup () {vfsstream: setup ($ this-> _ rootconfigdir);} protected function teardown () {} public function testfailedloadconfig () {$ this-> setexpectedexception ('restinyfilenotfound Exception ', 'resource1 config file not found'); configloader: loadconfig ('resource1');}/***/Public Function testloadconfig () {$ dir = vfsstream:: newdirectory ($ this-> _ configdir)-> at (vfsstreamwrapper: getroot (); $ file = vfsstream: newfile ($ this-> _ configfile) -> at ($ DIR); $ DATA = array ('/feed /(? <Name> [a-zA-Z_0-9] +) '=>'/feed', 'A' => '2', 'B' => 3); $ filecontent = '<? PHP '. php_eol; $ filecontent. = 'Return '; $ filecontent. = var_export ($ data, true); $ filecontent. = '; $ file-> setcontent ($ filecontent); $ Config = configloader: loadconfig ($ this-> _ configfilename, vfsstream :: URL ($ this-> _ configdir); $ this-> assertequals ($ data, $ config); $ this-> assertequals ('2 ', $ config ['a']); $ this-> assertequals (2, $ config ['a']); $ this-> assertnull ($ config ['C']) ;}}?>

Next we will explain this test case separately.

The test case configloadertest calls the static method setup () of the vfsstream class in the setup () method (). The Code is as follows:

protected function setUp() {vfsStream::setup($this->_rootConfigDir);}

Vfsstream: setup is an encapsulation of the vfsstream startup process. The function prototype is as follows:

    public static function setup($rootDirName = 'root', $permissions = null)    {        vfsStreamWrapper::register();        $root = self::newDirectory($rootDirName, $permissions);        vfsStreamWrapper::setRoot($root);        return $root;    }

Vfsstream: After setup () is executed, the vfsstream is created and has a root node with the default value "root.

The following code is available in testloadconfig:

$dir = vfsStream::newDirectory($this->_configDir)->at(vfsStreamWrapper::getRoot());

This line of code is used to create a folder and add it to the node. In this case, the URL of this folder is VFS: // root/dirname

Then the code will be executed:

$file = vfsStream::newFile($this->_configFile)->at($dir);

This line of code creates a file and adds it to the previously created folder. The File URL is VFS: // root/dirname/filename.

Next:

$data= array('/feed/(?<name>[a-zA-Z_0-9]+)' => '/feed','a' => '2','b' => 3);$fileContent = '<?php' . PHP_EOL;$fileContent .= 'return ';$fileContent .= var_export($data, true);$fileContent .= ';';$file->setContent($fileContent);

These lines of code construct a string as the content of the new file and use the setcontent () method to write the content to the file.

$config = ConfigLoader::loadConfig($this->_configFileName, vfsStream::url($this->_configDir));$this->assertEquals($data, $config);$this->assertEquals('2', $config['a']);$this->assertEquals(2, $config['a']);$this->assertNull($config['c']);

Next, pass the configuration file name to be loaded and the path of the folder where the configuration file is located to the configloader: loadconfig method, and assert.

The code above demonstrates some basic vfsstream functions. Vfsstream can also simulate file or folder permissions and groups with powerful functions.

It is the class graph of vfsstream I have drawn, which gives you a simple understanding of the structure of vfsstream.

Vfsstream resources:

Project home: http://code.google.com/p/bovigo/wiki/vfsStream

<Vfsstream-valid tive filesystem mocking>: http://www.slideshare.net/proofek/vfsstream-effective-filesystem-mocking

<Vfsstream-a better approach for file system dependent tests>: http://talks.frankkleine.de/ipc_vfsStream.pdf

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.