Question

I am trying to write a tests for my image upload library Bulletproof.

The problem is that, even though I know the basics of Unit Testing. I have a problem writing one for file uploads.

As far as my experience goes, I have only wrote very simple ones like check HTTP status corresponds some number, or check a link/div exists in a some page or assert the outcome of some function or class is similar and such and such..

But with image upload it is completely different scenario. Specially in this case, the class provides uploading, cropping, resizing and watermarking. So, seems writing an automated test case that checks each image is manipulated accordingly seems impossible for file uploads.

I'm hoping anyone can she some light on this problem.

Was it helpful?

Solution 2

Since this question has not been answered (rightly) for 2 years, I've decided to answer it myself since I have figured out the solution since then.

The answer turns out simple than I had thought, which simply is known as 'mocking'. In this case, when testing a file/image upload script, there is no physically upload images. All can be done with refactoring and isolating the function responsible for uploading, as in ..

Example of upload class

class Upload{
    function save(){
        return move_uploaded_file($tmp_name, $destination);
    }
}

Example of using test for the upload class

class UploadTest{
    function save(){
        return true; 
    }
}

There is nothing much into this, as method save() does not need to be tested considering it does not rely anymore on the class to upload the files/images

OTHER TIPS

A useful heuristic you might want to always keep in mind is this: when designing unit tests is hard, most of the times that's an indication of a design problem in the code you're trying to test. This turns the problem around, from a testing problem to a design problem. You can then think about design principles that might have been violated and that can indicate the general strategy to fix the situation.

As you point out, the Bulletproof class does a lot of things: uploading, cropping, resizing and watermarking. It also has to interact with the file system, the PHP environment, the HTTP context, etc. Sounds like this class is violating Uncle Bob's "Single Responsibility Principle": the idea that classes should do only one thing, or more precisely, have a single reason to change.

The solution to your problem, then, is to break apart this big class into a a bunch of smaller classes that are responsible for individual features. Those classes will be smaller and simpler to test.

For example, you could extract one class that knows how to apply a watermark, another that knows how to resize an image, etc.

To deal with external dependencies, like the file system or the HTTP context, you apply the same idea (extracting a class for each), and you define an interface (or abstract class) for those, so your other code doesn't depend directly on the implementation, but instead access it through a narrow, very specific interface. Then, in your tests you provide mocks to avoid having to deal with real files, real HTTP connections, etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top