I’m writing an upload function for ColdFusion of Wheels and need to unit test it once it’s finished. The problem I’m having though is that I have no idea on how to create a mock multi-part form post in ColdFusion that I can use in my unit tests.
What I would like to be able to do is create the mock request simulating a file being uploaded that cffile could then process and I could check against.
I saw in the online ColdFusion help, an example of creating such a request using cfhttp, however it has to post to another page which kind of defeats that whole purpose.
Great question rip. For what it’s worth, I contribute to MXUnit (wrote the eclipse plugin) and this scenario came up in a presentation I did at cfobjective this year on writing easier-to-test code (http://mxunit.org/doc/zip/marc_esher_cfobjective_2009_designing_for_easy_testability.zip).
In this scenario, I’d suggest NOT testing the upload. I believe we shouldn’t spend time testing stuff that’s not our code. The likelihood that we’ll catch a bug or other oddity is sufficiently low for me to justify leaving it untested. I believe we should be testing “our” code, however.
In your scenario, you have two behaviors: 1) the upload and 2) the post-upload behavior. I’d test the post-upload behavior.
This now frees your unit test to not care about the source of the file. Notice how this actually results in a decoupling of the upload logic from the “what do I do with the file?” logic. Taken to its conclusion, this at least creates the potential (theoretically) to reuse this post-upload logic for stuff other than just uploads.
This keeps your test much easier, because now you can just test against some file that you put somewhere in the setUp of the unit test itself.
So your component changes from
to
and then
or “handleFile” or “doSomethingWithFile” or “processNetworkFile” or some other thing. and in your unit test, you leave upload() untested and just test your post-upload handler. For example, if I were doing this at work, and my requirements were: “Upload file; move file to queue for virus scanning; create thumbnails if image or jpg; add stuff to database; etc” then I’d keep each of those steps as separate functions, and I’d test them in isolation, because I know that “upload file” already works since it’s worked since CF1.0 (or whatever). Make sense?
Better yet, leave the “upload” out of the component entirely. nothing wrong with keeping it in a CFM file since there’s kind of not much point (as far as I can see) in attempting to genericize it. there might be benefits where mocking is concerned, but that’s a different topic altogether.