Your SlideShare is downloading. ×

vfsStream - effective filesystem mocking

5,648

Published on

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,648
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
28
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Not full support Helps test things like is_readable(), is_writable() or is_executable() Default file mode 0666 Default dir mode 0777 Subdirs get parents perms
  • Transcript

    • 1. VfsStream effective filesystem mocking Sebastian Marek
    • 2. Prerequisites
      • some experience in unit testing
      • 3. basic knowledge of PHPUnit
    • 4. External dependencies
    • 7. Filesystem
      • Easy to set up
      • 8. Many different ways
      • 9. Not a dependency
      REALLY!?
    • 10. Learning by example <?php class Config { private $filename ; public function __construct($filename) { if (!is_file($filename)) { throw new Exception( &quot;Can't set the filename - it doesn't exists!&quot; ); } $this -> filename = $filename; } public function fetchConfig() { return parse_ini_file( $this -> filename , true ); } public function createCacheDir($directory) { if (!is_dir($directory)) { return mkdir($directory, 0700, true ); } return false ; } }
    • 11. guerrillas
      • setUp and tearDown
      • 12. prepare upfront
      http://picasaweb.google.co.uk/catof.airsoft/PartisanRusse#5480348761446205778
    • 13. guerrillas test case <?php class ConfigTest extends PHPUnit_Framework_TestCase { private $cacheDir = '/tmp/cache' ; private $configFile = '/tmp/config.ini' ; // (...) /** * @covers Config::__construct */ public function testConstructorSetsConfigFilename() { $config = new Config( $this -> configFile ); $this ->assertAttributeEquals( $this -> configFile , 'filename' , $config); } // (...) }
    • 14. guerrillas test case <?php class ConfigTest extends PHPUnit_Framework_TestCase { private $cacheDir = '/tmp/cache' ; private $configFile = '/tmp/config.ini' ; // (...) /** * @covers Config::__construct */ public function testConstructorThrowsExceptionWithInvalidConfigFile() { $configFile = '/share/usr/config.ini' ; $this ->setExpectedException( 'Exception' , &quot;Can't set the filename - it doesn't exists!&quot; ); $config = new Config($configFile); } // (...) }
    • 15. guerrillas test case <?php class ConfigTest extends PHPUnit_Framework_TestCase { private $cacheDir = '/tmp/cache' ; private $configFile = '/tmp/config.ini' ; protected function setUp() { $content = &quot; [section1] key1=value1 key2=value3 [section2] key3=value3 &quot; ; file_put_contents( $this -> configFile , $content); if (!is_dir( $this -> cacheDir )) { mkdir( $this -> cacheDir ); } } // (...) }
    • 16. guerrillas test case class ConfigTest extends PHPUnit_Framework_TestCase { private $cacheDir = '/tmp/cache' ; private $configFile = '/tmp/config.ini' ; // (...) protected function tearDown() { if (is_dir( $this -> cacheDir )) { rmdir( $this -> cacheDir ); } unlink( $this -> configFile ); } // (...) }
    • 17. Modern warfare vfsStream
      • mocks away filesystem
      • 18. uses php stream wrapper
      http://picasaweb.google.co.uk/dawson.jerome/MCASMiramarAirShow2007#5121760885155756402
    • 19. vfsStream installation #> pear channel-discover pear.php-tools.net #> pear install pat/vfsStream-alpha
    • 20. vfsStream - register <?php require_once 'vfsStream/vfsStream.php' // (...) protected function setUp() { vfsStream:: setup ( 'root' ); } // (...)
    • 21. vfsStream & PHPUnit <?php class SomeTest extends PHPUnit_Framework_TestCase { protected function setVfsStream() { @ include_once 'vfsStream/vfsStream.php' ; if (!class_exists( 'vfsStreamWrapper' )) { $this ->markTestSkipped( 'vfsStream is not available - skipping' ); } else { vfsStream:: setup ( 'root' ); } } public function testSomething() { $this ->setVfsStream(); //(...) } }
    • 22. vfsStream – working with files <?php class ConfigTest extends PHPUnit_Framework_TestCase { /** * @covers Config::__construct */ public function testConstructorSetsConfigFilename() { $this ->setVfsStream(); vfsStream::newFile( 'config.ini' )->at(vfsStreamWrapper::getRoot()); $config = new Config(vfsStream::url( 'root/config.ini' )); $this ->assertAttributeEquals(vfsStream::url( 'root/config.ini' ), 'filename' , $config); } // (...) }
    • 23. vfsStream – working with files <?php class ConfigTest extends PHPUnit_Framework_TestCase { /** * @covers Config::__construct */ public function testConstructorThrowsExceptionWithInvalidConfigFile() { $this ->setVfsStream(); $this ->setExpectedException( 'Exception' , &quot;Can't set the filename - it doesn't exists!&quot; ); $config = new Config(vfsStream::url( 'root/config.ini' )); } // (...) }
    • 24. vfsStream url <?php // (...) public function dumpVfsStreamUrl () { $this ->setVfsStream(); echo vfsStream::url( 'root/config.ini' ); // vfs://root/config.ini } // (...) }
    • 25. vfsStream – working with dirs <?php class ConfigTest extends PHPUnit_Framework_TestCase { /** * @covers Config::createCacheDir */ public function testCreateCacheDirIfItDoesntExists() { $this ->setVfsStream(); $this ->assertFileNotExists(vfsStream:: url ( 'root/cache' )); vfsStream:: newFile ( 'config.ini' )->at(vfsStreamWrapper:: getRoot ()); $config = new Config(vfsStream:: url ( 'root/config.ini' )); $config->createCacheDir(vfsStream:: url ( 'root/cache' )); $this ->assertFileExists(vfsStream:: url ( 'root/cache' )); } // (...) }
    • 26. vfsStream – working with dirs <?php class ConfigTest extends PHPUnit_Framework_TestCase { /** * @covers Config::createCacheDir */ public function testDontCreateCacheDirIfItExists() { $this ->setVfsStream(); vfsStream:: newFile ( 'config.ini' )->at(vfsStreamWrapper:: getRoot ()); vfsStream:: newDirectory ( 'cache' )->at(vfsStreamWrapper:: getRoot ()); $this ->assertFileExists(vfsStream:: url ( 'root/cache' )); $config = new Config(vfsStream:: url ( 'root/config.ini' )); $result = $config->createCacheDir(vfsStream:: url ( 'root/cache' )); $this ->assertFalse($result); } // (...) }
    • 27. vfsStream – working with content <?php class ConfigTest extends PHPUnit_Framework_TestCase { /** * @covers Config::fetchConfig */ public function testFetchConfigReturnsArray() { $this ->setVfsStream(); $content = << < 'EOT' [section1] key1 = value1 [section2] key2 = value2 [section3] key3 = value3 EOT; vfsStream:: newFile ( 'config.ini' )->withContent($content) ->at(vfsStreamWrapper:: getRoot ()); $config = new Config(vfsStream:: url ( 'root/config.ini' )); $result = $config->fetchConfig(); $this ->assertTrue(is_array($result)); $this ->assertEquals(3, count($result)); $this ->assertEquals( array ( 'key1' => 'value1' ), $result[ 'section1' ]); $this ->assertEquals( array ( 'key2' => 'value2' ), $result[ 'section2' ]); $this ->assertEquals( array ( 'key3' => 'value3' ), $result[ 'section3' ]); } }
    • 28. vfsStream – file perms new vfsStreamFile( 'app.ini' , 0644); new vfsStreamDirectory( '/home' , 0755); vfsStream:: newFile ( 'app.ini' , 0640); vfsStream:: newDirectory ( '/tmp/cache' , 0755); $vfsStreamFile->chmod(0664); $vfsStreamDirectory->chmod(0700);
    • 29. vfsStream – file ownership $vfsStreamFile->chown(vfsStream:: OWNER_USER_2 ); $vfsStreamDirectory->chown(vfsStream:: OWNER_ROOT ); $vfsStreamFile->chgrp(vfsStream:: GROUP_USER_2 ); $vfsStreamDirectory->chgrp(vfsStream:: GROUP_ROOT );
    • 30. vfsStream – file ownership
      • vfsStream:: OWNER_ROOT // 0
      • 31. vfsStream:: OWNER_USER_1 // 1
      • 32. vfsStream:: OWNER_USER_2 // 2
      • vfsStream:: GROUP_ROOT // 0
      • 33. vfsStream:: GROUP_USER_1 // 1
      • 34. vfsStream:: GROUP_USER_2 // 2
    • 35. Known limitations
      • umask() is ignored
      • 36. chmod() , chown() , chgrp(), tempnam() doesn't work with streams
      • 37. no support for fileatime() and filectime()
      • 38. realpath() and touch() does not work with any other URLs than pure filenames
      • 39. Smarty doesn't like it ;(
    • 40. vfsStream PHPUnit Helper
      • simplified integration with PHPUnit
      • 41. skips when vfsStream not installed
      • 42. unified interface
    • 43. vfsStream PHPUnit Helper <?php class MyClassTest extends PHPUnit_Framework_TestCase { // (...) /** * - It will skip the test if vfsStream is not installed * - It will register vfsStream in default root directory called 'root' * - creates 'tmp' directory in root directory */ public function testCreateDirectoryInDefaultRootDirectory() { $vfsStreamWrapper = new vfsStreamHelper_Wrapper( $this ); $vfsStreamWrapper->createDirectory( &quot;tmp&quot; ); $this ->assertFileExists(vfsStream:: url ( 'root/tmp' )); } // (...) }
    • 44. vfsStream PHPUnit Helper <?php class MyClassTest extends PHPUnit_Framework_TestCase { // (...) /** * - It will skip the test if vfsStream is not installed * - It will register vfsStream in default root directory called 'root' * - creates empty 'myFile.txt' file in root directory */ public function testCreateEmptyFileInDefaultRootDirectory() { $vfsStreamWrapper = new vfsStreamHelper_Wrapper( $this ); $vfsStreamWrapper->createFile( &quot;myFile.txt&quot; ); $this ->assertFileExists(vfsStream:: url ( 'root/myFile.txt' )); } // (...) }
    • 45. vfsStream PHPUnit Helper <?php class MyClassTest extends PHPUnit_Framework_TestCase { // (...) /** * - It will skip the test if vfsStream is not installed * - It will register vfsStream in root directory called 'myDir' * - creates 'home' directory in root directory */ public function testCreateDirectoryInCustomRootDirectory() { $vfsStreamWrapper = new vfsStreamHelper_Wrapper( $this , 'myDir' ); $vfsStreamWrapper->createDirectory( &quot;home&quot; ); $this ->assertFileExists(vfsStream:: url ( 'myDir/home' )); } // (...) }
    • 46. vfsStream PHPUnit Helper <?php class MyClassTest extends PHPUnit_Framework_TestCase { // (...) /** * - It will skip the test if vfsStream is not installed * - It will register vfsStream in default root directory called 'root' * - creates directory in different possible ways */ public function testDifferentWaysOfCreatingDirectories() { $vfsStreamWrapper = new vfsStreamHelper_Wrapper( $this ); // create a single directory $vfsStreamWrapper->createDirectory( &quot;tmp&quot; ); // create nested directories $vfsStreamWrapper->createDirectory( &quot;home/proofek/downloads&quot; ); // create a directory using vfsStreamHelper_Directory in default root $vfsStreamWrapper->createDirectory( new vfsStreamHelper_Directory( 'etc' )); // create a directory using vfsStreamHelper_Directory in a subdirectory $vfsStreamWrapper->createDirectory( new vfsStreamHelper_Directory( 'init.d' , 'etc' ) ); // (...)
    • 47. vfsStream PHPUnit Helper // (...) // create multiple directories $vfsStreamWrapper->createDirectory( array ( new vfsStreamHelper_Directory( 'user1' , 'home' ), new vfsStreamHelper_Directory( 'user2' , 'home' ), new vfsStreamHelper_Directory( 'usr' ), ) ); } // (...) }
    • 48. vfsStream PHPUnit Helper <?php class MyClassTest extends PHPUnit_Framework_TestCase { // (...) /** * - It will skip the test if vfsStream is not installed * - It will register vfsStream in default root directory called 'root' * - creates files in different possible ways */ public function testDifferentWaysOfCreatingFiles() { $vfsStreamWrapper = new vfsStreamHelper_Wrapper( $this ); // create a single empty file in default root directory $vfsStreamWrapper->createFile( &quot;myFile.txt&quot; ); // create a single empty file using vfsStreamHelper_File in default root $vfsStreamWrapper->createFile( new vfsStreamHelper_File( 'anotherFile.txt' ) ); // create a single file with contents using vfsStreamHelper_File in default root $fileContent = &quot;First line in the file Second line in the file &quot; ; $vfsStreamWrapper->createFile( new vfsStreamHelper_File( 'thirdFile.txt' , $fileContent) ); // (...)
    • 49. vfsStream PHPUnit Helper // (...) // create a single file with contents using vfsStreamHelper_File in // a subdirectory $fileContent = &quot;First line in the file Second line in the file &quot; ; $vfsStreamWrapper->createDirectory( &quot;tmp&quot; ); $vfsStreamWrapper->createFile( new vfsStreamHelper_File( 'file.txt' , $fileContent, 'tmp' ) ); // create multiple files $vfsStreamWrapper->createDirectory( &quot;etc&quot; ); $vfsStreamWrapper->createFile( array ( new vfsStreamHelper_File( 'file1.txt' , 'some content' , 'etc' ), new vfsStreamHelper_File( 'file2.txt' , null , 'etc' ), new vfsStreamHelper_File( 'file3.txt' ), ) ); } // (...) }
    • 50. Need help? Resources
      • http://code.google.com/p/bovigo/wiki/vfsStream
      • 51. http://www.php.net/manual/en/book.stream.php
      • 52. http://github.com/proofek/vfsStreamHelper
      Me
      • twitter - @proofek
      • 53. github - http://github.com/proofek

    ×