Home >Backend Development >Golang >How to Effectively Mock Filesystem Interactions for Unit Testing in Go?
Testing Filesystem Interaction in Go with Mocks
Mocking the filesystem can be valuable when unit testing functions that interact with the filesystem. To demonstrate its usage, let's examine an interface-based approach, where we create a custom fileSystem interface that encapsulates the filesystem operations.
var fs fileSystem = osFS{} type fileSystem interface { Open(name string) (file, error) Stat(name string) (os.FileInfo, error) } type file interface { io.Closer io.Reader io.ReaderAt io.Seeker Stat() (os.FileInfo, error) } // osFS implements fileSystem using the local disk. type osFS struct{} func (osFS) Open(name string) (file, error) { return os.Open(name) } func (osFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) }
Mock Implementation:
To mock the filesystem, we can create a mocked version of the fileSystem interface, called mockedFS. This allows us to control the behavior of the filesystem operations during testing.
Example Function:
Let's consider a function getSize that returns the file size using the filesystem.Stat method:
func getSize(name string) (int64, error) { stat, err := fs.Stat(name) if err != nil { return 0, err } return stat.Size(), nil }
Setting Up the Mock:
Before testing getSize, we need to replace the global fs variable with our mocked instance:
func TestGetSize(t *testing.T) { // Save the original filesystem oldFs := fs // Replace with mocked filesystem mfs := &mockedFS{} fs = mfs // Restore original filesystem after test defer func() { fs = oldFs }() }
Test Execution:
The test code below verifies the getSize function's behavior under various error and file size conditions:
type mockedFS struct { reportErr bool reportSize int64 } func (mfs) Stat(name string) (os.FileInfo, error) { if mfs.reportErr { return nil, os.ErrNotExist } return &mockedFileInfo{size: mfs.reportSize}, nil } type mockedFileInfo struct { size int64 } func (mfi mockedFileInfo) Size() int64 { return mfi.size } // Test Error Case func TestGetSize(t *testing.T) { ... mfs.reportErr = true if _, err := getSize("hello.go"); err == nil { ... } // Test Non-Error Case func TestGetSize(t *testing.T) { ... mfs.reportSize = 123 if size, err := getSize("hello.go"); ... }
This example demonstrates how to create a custom filesystem interface, mock its implementation, and use it to test a function that interacts with the filesystem, ensuring a controlled testing environment in Go.
The above is the detailed content of How to Effectively Mock Filesystem Interactions for Unit Testing in Go?. For more information, please follow other related articles on the PHP Chinese website!