16

I'm using simpleTest to write my PHP tests. I'm writing a file upload plugin and was wondering how I may be testing it.

I would like to check that the file is correctly uploaded, in the right folder, that error are correctly returned when needed, etc.

How do I emulate a file upload (through the $_FILES variable) ? Are there any issues I should be aware of ?

pixelastic
  • 5,138
  • 6
  • 24
  • 29

4 Answers4

28

I've found an alternate solution. I've spoofed the $_FILES array with test data, created dummy test files in the tmp/ folder (the folder is irrelevant, but I tried to stick with the default).

The problem was that is_uploaded_file and move_uploaded_file could not work with this spoofed items, because they are not really uploaded through POST. First thing I did was to wrap those functions inside my own moveUploadedFile and isUploadedFile in my plugin so I can mock them and change their return value.

The last thing was to extends the class when testing it and overwriting moveUploadedFile to use rename instead of move_uploaded_file and isUploadedFile to use file_exists instead of is_uploaded_file.

pixelastic
  • 5,138
  • 6
  • 24
  • 29
  • 2
    Expanding this answer with how to mock the moving of files in move_uploaded_file would be very helpful. – David Yell Dec 01 '14 at 09:55
  • @pixelastic Any chance you could show us your code for that? – Magiranu Nov 18 '17 at 17:17
  • Unfortunately this question is more than 7 years old and I don't have access to this code anymore (plus, there was so many major PHP versions since then I don't think my code would still work). – pixelastic Nov 21 '17 at 08:28
9

According to the Docs, SimpleTest has support for FileUpload testing baked in since version 1.0.1:

File upload testing     Can simulate the input type file tag    1.0.1

I've looked over the examples at their site and would assume you'd use something along the lines of

$this->get('http://www.example.com/');
$this->setField('filename', 'local path');
$this->click('Go');

to submit the file and then use the regular assertions to check the upload worked as wanted. But that's really just a wild guess, since I am not familiar with SimpleTest and I couldnt find an example at their homepage. You might want to ask in their support forum though.

But basically, there is not much use testing that a form uploads a file. This is tried and tested browser behavior. Testing the code that handles the upload makes more sense. I dont know how you implemented your FileUpload code, but if I had to implement this, I would get rid of the dependency on the $_FILES array as the first thing. Create a FileRequest class that you can pass the $_FILES array to. Then you can handle the upload from the class. This would allow you to test the functionality without actually uploading a file. Just setup your FileRequest instance accordingly. You could even mock the filesystem with vfsStreamWrapper, so you dont even need actual files.

Gordon
  • 312,688
  • 75
  • 539
  • 559
  • I want to be able to test only small fractions of my plugin. Doing a whole get request won't get me the level of detail I need. – pixelastic Aug 04 '10 at 23:28
5

You can generate a file upload in a programmatic manner with e.g. the curl extension.

Since this requires PHP running under a web server, it's not much of a unit test. Consequently, the best way would be to to use PHPT tests and fill the --POST_RAW-- section with the data.

If you don't know what to put in the --POST_RAW--, try to install the TamperData Firefox extension, do a file submission from Firefox, and copy-paste the data from the right side.

Artefacto
  • 96,375
  • 17
  • 202
  • 225
  • As you said, cURL is not so good for unit testing. I read the PHPT documentation and I think that may be the better solution. Unfortunatly I did not managed to get it to work... I finally found an other solution (see my answer) – pixelastic Aug 04 '10 at 23:28
  • I also tried using PHPT and --POST_RAW-- but couldn't get it to work either, as documented here: http://stackoverflow.com/questions/4974727/phpt-unable-to-run-sample-tests-that-use-post-raw – Ian Feb 12 '11 at 04:27
-2

For unit testing (as opposed to functional testing) try uploading a file (a short text file) to a test page, and var_dump($_FILES) and var_dump($_POST). Then you know what to populate them (or your mocks) with.

Nathan MacInnes
  • 11,033
  • 4
  • 35
  • 50