Reputation: 22385
I want to write a unit test that reads/writes files, so I made a helper func that makes a tempfile (adapted from Apple's docs):
func mkTmp() -> URL {
let fileManager = FileManager.default
let directory = fileManager.temporaryDirectory
let filename = UUID().uuidString
let fileURL = directory.appendingPathComponent(filename)
addTeardownBlock {
do {
if fileManager.fileExists(atPath: fileURL.path) {
try fileManager.removeItem(at: fileURL)
XCTAssertFalse(fileManager.fileExists(atPath: fileURL.path))
}
} catch {
XCTFail("Error while deleting temporary file: \(error)")
}
}
do {
try fileManager.createDirectory(at: fileURL, withIntermediateDirectories: true)
// FIXME: this always fails for some reason
XCTAssertTrue(fileManager.createFile(atPath: fileURL.path, contents: "test".data(using: .utf8)))
} catch {
XCTFail("Error while making temp dir: \(error)")
}
return fileURL
}
The problem is that createFile
line near the end. It always fails! Do unit tests not have write permissions on the temporary directory?
If I ignore that failure and just try to write to the file
let file = try FileHandle(forWritingTo: mkTmp())
defer { file.closeFile() }
file.write(data)
I get an error that the file doesn't exist when I try to open the file handle.
Do I need to set up file writing permissions somewhere for my unit test?
Upvotes: 5
Views: 4559
Reputation: 56635
The file cannot be created because a directory already exist at that url/path—which was created by fileManager.createDirectory(at: fileURL, ...)
. You can confirm this by adding these assertions to check what exists at fileURL
after calling fileManager.createDirectory(at: fileURL, ...)
:
try fileManager.createDirectory(at: fileURL, withIntermediateDirectories: true)
var isDirectory: ObjCBool = false
XCTAssertTrue(fileManager.fileExists(atPath: fileURL.path, isDirectory: &isDirectory))
XCTAssertTrue(isDirectory.boolValue)
To be able to create the file at fileURL
you only want to create its parent directory:
try fileManager.createDirectory(at: fileURL.deletingLastPathComponent(), withIntermediateDirectories: true)
Upvotes: 5