I’m working on a portion of my latest application that will need a facility to upload files. As these files are not images, I decided to use the plug-in attachment_fu. The thing that has caused me the most head scratching was how to set up unit tests to work with attachment_fu.
The class stores files related to a product. These are either code exerts or documentation. I’ve called the class ProductFile.
Params
If you are going to run tests that pass in data via a params hash, how do you get a file into the params in the right format. Here is the solution I worked out:
test_file = ActionController::TestUploadedFile.new(test_file_path)
@product_file_params = {
product_id => 1,
:document_type => 'document',
:version => 2,
:uploaded_data => test_file
}
I couldn’t get this to work without having the test file in a sub-folder of the fixtures folder. So I added a file ‘test/fixtures/files/test.txt’. Then I used ActionController::TestCase.fixture_path to determine the path.
Tear down
The other problem I had was that the standard Rails unit test tear down process wasn’t removing files created during the test. I overcame this by keeping track of each ProductFile created during the tests, and then using a teardown method to remove them all at the end of the test. This is the code that achieved that:
def create_product_file_from_params(params_mod = {})
product_file = ProductFile.create(@product_file_params.merge(params_mod))
@@created_product_files << product_file
return product_file
end
def teardown
remove_product_files_created_during_test
end
def remove_product_files_created_during_test
for product_file in @@created_product_files
product_file.destroy if product_file.filename
end
end
Now, as long as I used the create_product_file_from_params to create new product_files with params, the test would clean up after itself.
Fixtures
By the way, Product Files created via fixtures didn’t create a matching file in the file system. Which make it easier to keep things tidy, but needs to be kept in mind if you need an actual file to test against.
References
Mike Clark’s example of using attachment_fu
David Jones’ very interesting article on using attachment_fu with acts_as_versioned