测试从同一个 class 调用另一个的静态方法
Test static method that call another from same class
我有一个 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;
}
}
我想测试directoryExists
静态方法:
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'));
}
从 directoryExists
方法开始,getStorage
方法不是 return 模拟值而是 return 真实值。有什么想法吗?
如何测试从同一个 class 调用另一个静态方法?
不不不。 您必须模拟依赖项,而不是测试代码。
静态函数是糟糕的测试设计。
如果函数不是静态的,您可以使用 Filesystem
并模拟它们。
在这种情况下,最好的方法是 mock
使用 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));
}
已更新
或者,如果你使用Laravel,你可以使用File
门面:
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));
}
我有一个 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;
}
}
我想测试directoryExists
静态方法:
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'));
}
从 directoryExists
方法开始,getStorage
方法不是 return 模拟值而是 return 真实值。有什么想法吗?
如何测试从同一个 class 调用另一个静态方法?
不不不。 您必须模拟依赖项,而不是测试代码。 静态函数是糟糕的测试设计。
如果函数不是静态的,您可以使用 Filesystem
并模拟它们。
在这种情况下,最好的方法是 mock
使用 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));
}
已更新
或者,如果你使用Laravel,你可以使用File
门面:
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));
}