<?xml version="1.0" encoding="UTF-8"?>
<article-node>
  <account-id type="integer">2</account-id>
  <author>Christopher Haupt</author>
  <aux>Recently, I needed to write my first set of functional tests for a form that is used to upload image assets into our Content Management System. I wanted to find something as easy as fixtures for testing this part of our program.</aux>
  <body>&lt;p&gt;Recently, I needed to write my first set of functional tests for a form that is used to upload image assets into our Content Management System. I wanted to find something as easy as fixtures for testing this part of our program.&lt;/p&gt;
&lt;p&gt;Whether you are using &lt;a href=&quot;http://techno-weenie.net/&quot;&gt;Rick Olson&amp;#8217;s&lt;/a&gt; excellent attachment_fu (see &lt;a href=&quot;http://clarkware.com/cgi/blosxom/2007/02/24&quot;&gt;Mike Clark&amp;#8217;s nice tutorial&lt;/a&gt;), &lt;a href=&quot;http://uploadcolumn.rubyforge.org/&quot;&gt;Sebastian Kanthak and Jonas Nicklas&amp;#8217; upload_column&lt;/a&gt;, or your own code that works with file uploads, you should test this workflow just like any other code path. At first, I thought this was going to be a painful task and require messing around with some custom File I/O or other marshaling trickery. Most of the documentation for 3rd party file upload implementations tended to have little or no information on testing.&lt;/p&gt;
&lt;p&gt;Then, while reading through the code a bit more, I stumbled upon &lt;a href=&quot;http://api.rubyonrails.org/classes/ActionController/TestProcess.html&quot;&gt;fixture_file_upload&lt;/a&gt;. This convenience function is tucked away in ActionController&amp;#8217;s TestProcess module and is shorthand for instantiating the underlying ActionController::TestUploadedFile class. TestUploadedFile itself is a mock object that simulates the target file that my user would upload in a form or other interface via a &lt;span class=&quot;caps&quot;&gt;MIME&lt;/span&gt; multipart/form-data &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To use this handy method, I simply put test files in a convenient directory within my fixtures directory, say &amp;#8220;files&amp;#8221;. Then in a test for upload_column, I write:&lt;/p&gt;
&lt;pre&gt;
def test_should_create_asset
    old_count = Asset.count
    post :create, :asset =&amp;gt; { :title =&amp;gt; &quot;test&quot;, :file =&amp;gt; fixture_file_upload('/files/testpicture1.jpg', 'image/jpeg') }
    assert_equal old_count+1, Asset.count
    assert_redirected_to asset_path(assigns(:asset))
 end
&lt;/pre&gt;
&lt;p&gt;Here, the :file attribute for my asset model is expecting an uploaded file from my form, so I feed it one from my fixtures/files directory.&lt;/p&gt;
&lt;p&gt;If I use attachment_fu, I may write a create test:&lt;/p&gt;
&lt;pre&gt;
  def test_should_create_asset
    old_count = Asset.count
    post :create, :asset =&amp;gt; { :name =&amp;gt; 'railslogo', :uploaded_data =&amp;gt; fixture_file_upload('/files/rails.png', 'image/png') },
                   :html =&amp;gt; {:multipart =&amp;gt; true }
    assert_equal old_count+1, Asset.count

  end
&lt;/pre&gt;
&lt;p&gt;or an update test:&lt;/p&gt;
&lt;pre&gt;
  def test_should_update_asset
    put :update, {:id =&amp;gt; assets(:one).id, :asset =&amp;gt; { :uploaded_data =&amp;gt; fixture_file_upload('/files/rails.png', 'image/png') }}
    assert_redirected_to asset_path(assigns(:asset))
  end
&lt;/pre&gt;
&lt;p&gt;The TestUploadedFile class is not limited to image data. It can channel any type I may wish into the request. Its default content type assumes text/plain.&lt;/p&gt;
&lt;p&gt;Now I can proceed to write a suite of tests for my file upload use cases and let Action Controller and the fixture_file_upload helper do the heavy lifting.&lt;/p&gt;
&lt;h3&gt;Other Resources&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.subelsky.com/2007/05/functional-testing-for-attachment-fu.html&quot;&gt;Mike Subelsky&amp;#8217;s Blog Entry about testing Attachment_fu&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.beckshome.com/PermaLink,guid,560613dd-217c-4cb1-a6b9-df83a55191e7.aspx&quot;&gt;Thomas Beck&amp;#8217;s Blog Entry about multi-model tests with Attachment_fu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</body>
  <created-at type="datetime">2008-07-24T01:00:47-07:00</created-at>
  <created-by type="integer">2</created-by>
  <dy-schema-id type="integer" nil="true"></dy-schema-id>
  <dy-schema-type nil="true"></dy-schema-type>
  <filter-id nil="true"></filter-id>
  <flags type="integer">1</flags>
  <historic-id type="integer">10</historic-id>
  <id type="integer">6411</id>
  <kind-id type="integer">5019</kind-id>
  <lock-version type="integer">2</lock-version>
  <name>File Upload Form Testing Fixtures</name>
  <owner-id type="integer" nil="true"></owner-id>
  <owner-type nil="true"></owner-type>
  <published-at type="datetime">2008-02-04T16:00:00-08:00</published-at>
  <rating type="integer">3</rating>
  <ref-count type="integer">0</ref-count>
  <sequence type="integer">0</sequence>
  <status type="integer">0</status>
  <updated-at type="datetime">2009-03-19T11:30:40-07:00</updated-at>
  <updated-by type="integer">1</updated-by>
  <url nil="true"></url>
  <user-id type="integer">1</user-id>
  <version type="integer">4</version>
  <workflow-task-status-id type="integer" nil="true"></workflow-task-status-id>
</article-node>
