I am just now getting into formal unit testing and have come across an issue in testing separate internal parts of functions.
I have created a base class of data manipulation (i.e.- moving files, chmodding file, etc) and in moveFile()
I have multiple levels of validation to pinpoint when a moveFile()
fails (i.e.- source file not readable, destination not writeable).
I can't seem to figure out how to force a couple particular validations to fail while not tripping the previous validations.
Example:
I want the copying of a file to fail, but by the time I've gotten to the actual copying, I've checked for everything that can go wrong before copying.
Code Snippit: (Bad code on the fifth line...)
// if the change permissions is set, change the file permissions
if($chmod !== null)
{
$mod_result = chmod($destination_directory.DIRECTORY_SEPARATOR.$new_filename, $chmod);
if($mod_result === false || $source_directory.DIRECTORY_SEPARATOR.$source_filename == '/home/k...../file_chmod_failed.qif')
{
DataMan::logRawMessage('File permissions update failed on moveFile [ERR0009] - ['.$destination_directory.DIRECTORY_SEPARATOR.$new_filename.' - '.$chmod.']', sfLogger::ALERT);
return array('success' => false, 'type' => 'Internal Server Error [ERR0009]');
}
}
So how do I simulate the copy failing. My stop-gap measure was to perform a validation on the filename being copied and if it's absolute path matched my testing file, force the failure. I know this is very bad to put testing code into the actual code that will be used to run on the production server but I'm not sure how else to do it.
Note:
I am on PHP 5.2, symfony, using lime_test()
.
EDIT I am testing the chmodding and ensuring that the array('success' => false, 'type' => ..) is returned
2 Answers 2
So how do I simulate the copy failing.
You mock the chmod()
function so that it can return error status.
-
how would I go about mocking that in PHP? would it just be making a wrapper function to call instead of
chmod()
?Patrick– Patrick2011年02月08日 21:08:52 +00:00Commented Feb 8, 2011 at 21:08 -
@Patrick. Essentially, yes. You'd be happiest having your own 'chmod' function that has several implementations. One implementation calls the system function directly. The other throws errors for testing purposes. The idea is that your application code doesn't change, only the choice of which
chmod
to use changes.S.Lott– S.Lott2011年02月08日 21:14:24 +00:00Commented Feb 8, 2011 at 21:14
Hmm. It's tricky to get PHP's chmod() to fail. I did find one way, though not sure if it helps on your case. I assume an Unix environment, not sure how it would work on Windows.
chmod() will fail on "too many symbolic links", so try to set up a situation where you have a symbolic link pointing to itself. Something like:
ln -s foo.file foo.file
and now PHP's chmod("foo.file") will fail with
Warning: chmod(): Too many levels of symbolic links
So, if the foo.file above passes your other tests, it should fail on chmod().
-
thanks for the tip, I was at a loss for how to 'break'
chmod()
. I am on linuxPatrick– Patrick2011年02月08日 21:08:09 +00:00Commented Feb 8, 2011 at 21:08
logRawMessage
. About manipulating the files directly to cause the error, all the validation happens in the same function immediately before the attemptedchmod
so I don't believe I can do that. I hadn't thought of the wrapper function before that's just for testing. I do log the information when the function fails, that's what thelogRawMessage
is doing.