{"id":405,"date":"2013-08-21T13:47:27","date_gmt":"2013-08-21T13:47:27","guid":{"rendered":"http:\/\/nicholshayes.co.uk\/blog\/?p=405"},"modified":"2013-10-31T15:52:11","modified_gmt":"2013-10-31T15:52:11","slug":"functional-tests-with-carrierwave","status":"publish","type":"post","link":"http:\/\/nicholshayes.co.uk\/blog\/?p=405","title":{"rendered":"Functional tests with Carrierwave"},"content":{"rendered":"<p><a href=\"https:\/\/github.com\/carrierwaveuploader\/carrierwave\">Carrierwave<\/a> is a really nice gem to use when you want to upload and save a file within a ruby object. But how do you test it, if you don&#8217;t use anything more that test\/unit or minitest?<\/p>\n<p>Most of the articles describing testing Carrierwave rely on <a href=\"https:\/\/github.com\/carrierwaveuploader\/carrierwave\/blob\/master\/README.md#testing-with-carrierwave\">rspec<\/a> or <a href=\"http:\/\/infinite-sushi.com\/2010\/09\/testing-file-uploads-with-carrierwave\/\">capybara<\/a>, but I don&#8217;t like adding test gems unless I have to. I prefer to use the test objects provided within the ruby standard library. So test\/unit and minitest. <\/p>\n<p>Fortunately, it is fairly easy to manage without anything complicated. All you have to realise is that when a form is submitted to a controller, the uploaded file is presented within params via a ActionDispatch::Http::UploadedFile object. <\/p>\n<p>So for example, I have a model SupportingDocument, which has an attribute &#8216;document&#8217; that holds the CarrierWave::Uploader associated with uploaded files.<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\"><span class=\"kw1\">class<\/span> SupportingDocument <span class=\"sy0\">&lt;<\/span> <span class=\"re2\">ActiveRecord::Base<\/span><br \/>\n&nbsp; mount_uploader <span class=\"re3\">:document<\/span>, SupportingDocumentUploader<br \/>\n<span class=\"kw1\">end<\/span><\/div><\/div>\n<p>To functionally test the supporting_documents controller actions I added a couple of methods to my test SupportingDocumentsControllerTest, that create an UploadedFile object:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\">&nbsp; <span class=\"kw1\">def<\/span> file<br \/>\n&nbsp; &nbsp; <span class=\"re1\">@file<\/span> <span class=\"sy0\">||<\/span>= <span class=\"kw4\">File<\/span>.<span class=\"kw3\">open<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw4\">File<\/span>.<span class=\"me1\">expand_path<\/span><span class=\"br0\">&#40;<\/span> <span class=\"st0\">'..\/..\/file\/test.txt'<\/span>, <span class=\"kw2\">__FILE__<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; <span class=\"kw1\">end<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">def<\/span> uploaded_file_object<span class=\"br0\">&#40;<\/span>klass, attribute, file, content_type = <span class=\"st0\">'text\/plain'<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; filename = <span class=\"kw4\">File<\/span>.<span class=\"me1\">basename<\/span><span class=\"br0\">&#40;<\/span>file.<span class=\"me1\">path<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; klass_label = klass.<span class=\"me1\">to_s<\/span>.<span class=\"me1\">underscore<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"re2\">ActionDispatch::Http::UploadedFile<\/span>.<span class=\"me1\">new<\/span><span class=\"br0\">&#40;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; tempfile: file,<br \/>\n&nbsp; &nbsp; &nbsp; filename: filename,<br \/>\n&nbsp; &nbsp; &nbsp; head: <span class=\"sy0\">%<\/span>Q<span class=\"br0\">&#123;<\/span>Content<span class=\"sy0\">-<\/span>Disposition: form<span class=\"sy0\">-<\/span>data; name=<span class=\"st0\">&quot;#{klass_label}[#{attribute}]&quot;<\/span>; filename=<span class=\"st0\">&quot;#{filename}&quot;<\/span><span class=\"br0\">&#125;<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; content_type: content_type<br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; <span class=\"kw1\">end<\/span><\/div><\/div>\n<p>I was then able to use this object within a test:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\">&nbsp; <span class=\"kw1\">def<\/span> test_create<br \/>\n&nbsp; &nbsp; name = <span class=\"st0\">'new_supporting_document'<\/span><br \/>\n&nbsp; &nbsp; assert_difference <span class=\"st0\">'SupportingDocument.count'<\/span> <span class=\"kw1\">do<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; post<span class=\"br0\">&#40;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:create<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; supporting_document: <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: name,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description: <span class=\"st0\">'New supporting document'<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document: uploaded_file_object<span class=\"br0\">&#40;<\/span>SupportingDocument, <span class=\"re3\">:document<\/span>, file<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notification_id: notification.<span class=\"me1\">id<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">end<\/span><br \/>\n&nbsp; &nbsp; assert_response <span class=\"re3\">:redirect<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; supporting_document = SupportingDocument.<span class=\"me1\">last<\/span><br \/>\n&nbsp; &nbsp; assert_equal name, supporting_document.<span class=\"me1\">name<\/span><br \/>\n&nbsp; &nbsp; assert_equal<span class=\"br0\">&#40;<\/span><span class=\"kw4\">File<\/span>.<span class=\"me1\">basename<\/span><span class=\"br0\">&#40;<\/span>file.<span class=\"me1\">path<\/span><span class=\"br0\">&#41;<\/span>, supporting_document.<span class=\"me1\">document_identifier<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; <span class=\"kw1\">end<\/span><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Carrierwave is a really nice gem to use when you want to upload and save a file within a ruby object. But how do you test it, if you don&#8217;t use anything more that test\/unit or minitest? Most of the &hellip; <a href=\"http:\/\/nicholshayes.co.uk\/blog\/?p=405\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/405"}],"collection":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=405"}],"version-history":[{"count":10,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/405\/revisions"}],"predecessor-version":[{"id":433,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/405\/revisions\/433"}],"wp:attachment":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=405"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}