PHPUnit: Как я обманываю эту файловую систему?

Рассмотрим следующий сценарий (это не производственный код):

 class MyClass {
    public function myMethod() {
        // create a directory
        $path = sys_get_temp_dir() . '/' . md5(rand());
        if(!mkdir($path)) {
            throw new Exception("mkdir() failed.");
        }

        // create a file in that folder
        $myFile = fopen("$path/myFile.txt", "w");
        if(!$myFile) {
            throw new Exception("Cannot open file handle.");
        }
    }
}

Правильно, так какая проблема? В отчетах о покрытии кода эта строка не распространяется:

throw new Exception("Cannot open file handle.");

Это правильно, но поскольку я создаю папку выше логически, казалось бы невозможным сбой fopen() (за исключением, может быть, в экстремальных обстоятельствах, таких как диск со 100%).

Я мог бы игнорировать код из охвата кода, но это своего рода обман. Можно ли каким-либо образом высмеять файловую систему, чтобы она могла распознать myFile.txt и высмеять файловую систему, неспособную создать файл?

Ответ 2

Вы также можете разбить функцию на 2 метода, один для создания пути, а другой - для использования. Затем можно было бы провести индивидуальные тесты, чтобы обеспечить создание пути. Второй набор тестов может проверять и фиксировать исключение, когда вы пытаетесь использовать плохой путь.

Ответ 3

Да!

Вы должны каким-то образом ввести полный путь и не называть sys_get_temp_dir() прямо в этом методе.

Любой несуществующий путь должен вызвать проблему. Для этого вам не нужна VFS.

НО вы получите E_NOTICE (или предупреждение, возможно?) до того, как будет вызвано исключение. Поэтому вы должны сначала проверить is_writable и выбросить исключение, если оно вернет false.