Unit test in Laravel by example
Tags: laravel, php, unittest, filesystem
Published: 2023-12-18 11:21:41

Testing is fun! Don't take my word for it. You should probably try it yourself. To get familiar with testing or even get better at writing unit tests, you can learn from prominent open-source projects. Just open the project and go to the test folder. You might see things like feature tests, integration tests, or unit tests. Choose a unit test and go through the test files.

Here we go through the unit test of FileSystems in Laravel framework. 

The address is [tests/Filesystem/FilesystemTest.php](https://github.com/laravel/framework/blob/10.x/tests/Filesystem/FilesystemTest.php)


## Setting the Stage:
Before delving into the details of the unit test, let's set the stage by briefly introducing the Illuminate Filesystem component. This component provides a unified interface for interacting with file systems, allowing developers to perform tasks such as reading, writing, and manipulating files and directories.

## Test Class Overview:
The unit test is written in PHP using the PHPUnit testing framework. It is part of the Illuminate\Tests\Filesystem namespace and extends the PHPUnit\Framework\TestCase class. The test class covers a wide range of scenarios, including file retrieval, storage, line operations, permissions, directory manipulation, and more.

### Mock
The test file uses use Mockery framework. Sometimes we do not really want to call a piece of code, or send real emails or SMS. For instance, in file system testing, we do not want to create a real file. Instead, we use mock object to call the delete method. a mock is a stand-in for a real object. It pretends to be the real thing in a controlled way, allowing developers to test specific parts of their code independently. 

Take a look at the code below:
    ` $files = m::mock(Filesystem::class)->makePartial();
     $files->shouldReceive('deleteDirectory')->once()->andReturn(false);`

We use mock to create partial test doubles* and fake call deleteDirectory (We do not call it really, and we do not delete anything rather we return what we think the deleteDirectory method returns).

Now open the code and walk through it along with the following explanations. 

### Setting up Temporary Directory:
The test class employs a temporary directory for creating and testing files. The setupTempDir() method, annotated with @beforeClass, creates a temporary directory for testing, while tearDownTempDir() (annotated with @afterClass) cleans up the temporary directory after all tests have been executed.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yz9invrmfrqsr4yslkep.jpeg)

### Filesystem Initialization:
In various test methods, an instance of the Filesystem class is created to simulate real-world usage. This includes scenarios where files need to be created, modified, or deleted.

### Testing File Retrieval:
The testGetRetrievesFiles method ensures that the get method retrieves the correct content from a file, asserting that the retrieved content matches the expected value.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69af3h7nfb8xh0dhsc4z.jpeg)

### Testing File Storage:
The testPutStoresFiles method examines the put method's ability to store content in a file, with an assertion to validate that the file content matches the expected value.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmdgksv130hwaf1yikfg.jpeg)

### Lazy Collection for Lines:
The testLines method demonstrates the use of LazyCollection for working with lines in a file. It ensures that lines are read correctly and returned as a LazyCollection.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqyhmhbw8lgxgiuta58v.jpeg)

### File Replacement Operations:
The testReplaceCreatesFile and testReplaceInFileCorrectlyReplaces methods test the replace method, both for creating a file and for replacing content within an existing file.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5m9hhpd096ikvc41ygk.jpeg)

### Testing File Permissions:
The testSetChmod and testGetChmod methods focus on testing the _chmod_ method for setting and retrieving file permissions.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7patppsyse2l1w8scz52.jpeg)

### Directory and File Deletion:
The testDeleteRemovesFiles method checks the delete method's ability to remove both single files and arrays of files.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4vf40bj8o9yp6clu19o.jpeg)

### Prepending to Files:
The testPrependExistingFiles and testPrependNewFiles methods examine the prepend method's functionality for adding content to the beginning of a file.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdksiz0ck1nq66y4caci.jpeg)

### File Existence Checks:
The testMissingFile method checks the missing method for detecting the absence of a file.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gw5fkvkhbrjnm6y2bpct.jpeg)

### Directory Manipulation:
Methods like testDeleteDirectory, testDeleteDirectoryReturnFalseWhenNotADirectory, and testCleanDirectory focus on testing directory-related operations.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hciklp64vqwtits10rxj.jpeg)

### Macro Functionality:
The testMacro method demonstrates the ability to add macros dynamically to the Filesystem class.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hk0aps6q6tx0le7ccn8v.jpeg)

### Additional File and Directory Operations:
The testFilesMethod, testCopyDirectory, testMoveDirectory, and other methods cover a range of file and directory operations, ensuring correct behavior in various scenarios.

### Exception Handling:
Methods like testGetThrowsExceptionNonexisitingFile and testGetRequireThrowsExceptionNonExistingFile test the handling of FileNotFoundExceptions.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4u6tknqf7w2b7udfa23l.jpeg)


I hope this post helps you to get your testing skills even further.

> Test Doubles: In computer programming and computer science, programmers employ a technique called automated unit testing to reduce the likelihood of bugs occurring in the software. Frequently, the final release software consists of a complex set of objects or procedures interacting together to create the final result. In automated unit testing, it may be necessary to use objects or procedures that look and behave like their release-intended counterparts but are simplified versions that reduce the complexity and facilitate testing. A test double is a generic term used for these objects or procedures. 
> Wikipedia