Reputation: 1435
I have a class:
namespace Models;
use Contracts\PathContract;
class Path implements PathContract
{
public static function getStorage(string $type): string
{
return storage_path(config('logs.storage_path', 'logs'))
.DIRECTORY_SEPARATOR
.$type;
}
public static function directoryExists(string $type): bool
{
var_dump(Path::getStorage($type)); // output: .../logs/vendor/orchestra/testbench-core/laravel/storage/logs/myCustomType
if (is_dir(self::getStorage($type))) {
return true;
}
return false;
}
}
I would like test directoryExists
static method:
public function testDirectoryExists(): void
{
$path = Mockery::mock(Path::class)->makePartial();
$path->shouldReceive('getStorage')
->once()
->andReturn('/var/log');
var_dump($path::getStorage('blah blah blah')); // output: /var/log
$this->assertTrue($path::directoryExists('myCustomType'));
}
From directoryExists
method, getStorage
method doesn't return mock value but return real value. Any ideas ?
How can I test a static method that call another from same class ?
Upvotes: 0
Views: 898
Reputation: 2957
No no no. You MUST mock dependencies, not testing code. Static function is bad design for testing.
If the functions weren't static, you could use Filesystem
and mock them.
In this case, the best way is to mock
the directory by using temp
.
public function testDirectoryExists(): void
{
//prepare
$temp = sys_get_temp_dir();
$logsPath = 'logs';
$logsDir = $temp.DIRECTORY_SEPARATOR.$logsPath;
$type = 'someType';
mkdir($logsDir);
//mock
$this->app->useStoragePath($temp);
config()->set('logs.storage_path', $logsPath);
//assert not created
$this->assertFalse(Path::directoryExists($type));
//assert created
mkdir($logsDir.DIRECTORY_SEPARATOR.$type);
$this->assertTrue(Path::directoryExists($type));
}
Or, if you use Laravel, you can use File
facade:
public static function directoryExists(string $type): bool
{
return File::isDirectory(self::getStorage($type));
}
public function testDirectoryExists(): void
{
$type = 'myType';
$expectedDir = '/logs/vendor/orchestra/testbench-core/laravel/storage/logs/'.$type;
$mock = Mockery::mock(\Illuminate\Filesystem\Filesystem::class);
$mock->shouldReceive('isDirectory')
->with($expectedDir)
->andReturn(true);
$this->app->instance(\Illuminate\Filesystem\Filesystem::class, $mock);
$this->assertTrue(Path::directoryExists($type));
}
Upvotes: 2