PHPUnit 测试 ExpectedException 不抛出异常

PHPUnit testing ExpectedException not throwing exception

使用 Laravel 框架和 phpunit 进行单元测试。

我正在使用一个函数,该函数需要为要写入的文件创建目录,简而言之,该函数获取数据,将其写入临时文件并在完成后移动临时文件。

public function getDataAndStoreToCSVFile() {
    Log::info(date('Y-m-d H:i:s') . " -> " . __FILE__ . "::" . __FUNCTION__);
    try {
        // make sure directories exist
        if (!Storage::has($this->temporary_directory) || !Storage::has($this->storage_directory)) {
            $this->createDirectories();
        }

        // get full path of storage disk for files
        $diskPath = Storage::getAdapter()->getPathPrefix();

        // create a complete path to temporary file to allow tempnam to find the directory
        $full_temporary_file_path = $diskPath.$this->temporary_directory;

        // fetch stations, station networks and station params seperated by double new line,
        // will return FALSE if something is missing and file will not be created and not written to
        if($stations_data_array = $this->getCompleteStationsDataArray("\n\n")){

            // create temporary file
            $temporary_file = tempnam($full_temporary_file_path,'') ;

            // if both $temporary_file and $stations_data_array exist write entries to file one at a time in CSV format
            if (file_exists($temporary_file)) {
                $fp = fopen($temporary_file, 'a');
                foreach ($stations_data_array as $fields) {
                    if (is_object($fields) || is_array($fields)) {

                        // $fields is an array
                        $fields = (array)$fields;
                        fputcsv($fp, $fields);
                    } else {

                        // $fields is the separator
                        fwrite($fp, $fields);
                    }
                }

                // done writing, close file
                fclose($fp);

                // create new permanent name for $temporary_file in the storage directory "full_disk_path.storage_path.yyyymmddhhmmss.timestamp"
                $storage_file = $diskPath . $this->storage_directory . "/" . date('YmdHis') . "." . time();

                // rename $temporary_file to $storage_file
                if (!rename($temporary_file, $storage_file)) {
                    Log::error(__FILE__ . "::" . __FUNCTION__ . " : Failed to move temporary file from " . $this->temporary_directory . " to " . $this->storage_directory);
                }
            } else{
                Log::error(__FILE__ . "::" . __FUNCTION__ . " : Temporary file was not available or does not exist.");
            }
        } else {
            Log::error(__FILE__ . "::" . __FUNCTION__ . " : Temporary file was not created.");
        }
    } catch (\ErrorException $e) {
        // Catches missing directory or file, or tempnam couldn't find temporary storage path //Todo add test for this exception
        Log::error(__FILE__ . "::" . __FUNCTION__ . " : " . $e->getMessage());
    } catch (\Exception $e) {
        // Catches uncaught exceptions
        Log::error(__FILE__ . "::" . __FUNCTION__ . " : " . $e->getMessage());
    }
}

要测试目录丢失时是否抛出 ErrorException,此测试:

public function test_getDataAndStoreToCSVFile_handles_ErrorException() {

    // set up data
    $this->setup_all_data_for_getDataAndStoreToCsvFile_funtion();

    // mock class
    $mock = $this->getMockBuilder('App\Interfaces\Sources\IdbStationSourceInterface')

    // stub function createDirectories, will now return null and not create directories, missing directories will throw ErrorException
    ->setMethods(['createDirectories'])
    ->getMock();

    // expect the ErrorException to be thrown
    $this->expectException('ErrorException');

    // run function
    $mock->getDataAndStoreToCSVFile();
}

当我运行测试时,我的日志显示我陷入了:

} catch (\ErrorException $e) {
        // Catches missing directory or file, or tempnam couldn't find temporary storage path //Todo add test for this exception
        Log::error(__FILE__ . "::" . __FUNCTION__ . " : " . $e->getMessage());
}

但是我的终端显示:

1) Tests\Interfaces\Sources\IdbStationSourceInterfaceTest::test_getDataAndStoreToCSVFile_handles_ErrorException 断言 "ErrorException" 类型的异常被抛出失败。

我不知道从那里去哪里,我阅读并尝试了几件事,但很明显我做错了什么。

编辑 1:

尝试过:$this->setExpectedException("ErrorException");

但我得到以下信息:

1) Tests\Interfaces\Sources\IdbStationSourceInterfaceTest::test_getDataAndStoreToCSVFile_handles_ErrorException 错误:调用未定义的方法 Tests\Interfaces\Sources\IdbStationSourceInterfaceTest::setExpectedException()

那是因为你捕获了异常。 PHPUnits expectedException-method 仅注册未处理或重新抛出的异常。要么在你的 catch 块中重新抛出异常,要么只测试你在 catch 块中创建的日志条目。

function getDataAndStoreToCSVFile() 你只是抛出错误代码和消息。然后你可以在测试用例中使用这些断言。

/** *@expectedException ExampleException *@expectedExceptionCode ExampleException::EceptionCode */ public function test_getDataAndStoreToCSVFile_handles_ErrorException() {}