2017-06-28 35 views
1

次のコードでは、Rails 4.2アプリ(RSpec 3.5)およびShrine gem(ファイルアップロード用)のモデル仕様の画像検証をテストします。Rails:モデル仕様でのファイルアップロードの検証(Shrine gem)

私の質問は以下のとおりです。

  • あなたは次のテストを改善する方法や、それらの検証をテストするためのより良い方法を考えることができますか?
  • ファイルサイズ検証テストの速度を向上させるにはどうすればよいですか?可能であれば、実際に10MB以上のファイルをアップロードすることなくテストしたいと思います。

ファイルアップロードセットアップのその他の側面は、コントローラと機能仕様でテストされていますが、この質問とは関係ありません。 Rack::Test::UploadedFile介してアップロードをルーティング、直接テストで直接固定具や工場等を用い添付メタデータレコードを作成するのではなく

RSpec.describe ShareImage, :type => :model do 
    describe "#image", :focus do 
    let(:image_file) do 
     # Could not get fixture_file_upload to work, but that's irrelevant 
     Rack::Test::UploadedFile.new(File.join(
     ActionController::TestCase.fixture_path, 'files', filename)) 
    end 
    let(:share_image) { FactoryGirl.build(:share_image, image: image_file) } 
    before(:each) { share_image.valid? } 

    context "with a valid image file" do 
     let(:filename) { 'image-valid.jpg' } 
     it "attaches the image to this record" do 
     expect(share_image.image.metadata["filename"]).to eq filename 
     end 
    end 

    context "with JPG extension and 'text/plain' media type" do 
     let(:filename) { 'image-with-text-media-type.jpg' } 
     it "is invalid" do 
     expect(share_image.errors[:image].to_s).to include("invalid file type") 
     end 
    end 

    # TODO: Refactor the following test (it takes ~50 seconds to run) 
    context "with a >10mb image file" do 
     let(:filename) { 'image-11mb.jpg' } 
     it "is invalid" do 
     expect(share_image.errors[:image].to_s).to include("too large") 
     end 
    end 
    end 
end 

答えて

2

メタデータの抽出と検証を個別にテストすることをお勧めします。実際のI/Oでテストする必要のあるメタデータ抽出ですが、検証テストでは、実際に存在する必要のないメタデータをキャッシュファイルに割り当てることができます。

RSpec.describe ImageUploader do 
    def uploaded_file(metadata = {}) 
    Shrine.uploaded_file(
     "id"  => "123", 
     "storage" => "cache", 
     "metadata" => {"mime_type" => "image/jpeg", "size" => 100}.merge(metadata) 
    ) 
    end 

    let(:share_image) do 
    FactoryGirl.build(:share_image, image: uploaded_file(metadata).to_json) 
    end 

    let(:metadata) { Hash.new } 

    describe "validations" do 
    before(:each) { share_image.valid? } 

    context "when image is correct" do 
     it "passes" do 
     expect(share_image.errors).to be_empty 
     end 
    end 

    context "when extension is correct but MIME types isn't" do 
     let(:metadata) { Hash["filename" => "image.jpg", mime_type => "text/plain"] } 

     it "fails" do 
     expect(share_image.errors[:image].to_s).to include("isn't of allowed type") 
     end 
    end 

    context "when file is larger than 10MB" do 
     let(:metadata) { Hash["size" => 11 * 1024 * 1024] } 

     it "fails" do 
     expect(share_image.errors[:image].to_s).to include("too large") 
     end 
    end 
    end 
end 
+0

これは素晴らしいです!どうもありがとうございました。 – BrunoFacca

1

。最終結果として、ファイルをアップロードする際に作成された添付メタデータが、アップロードコードを通じて実行されることなくファイルを参照することになります。 Shrineでこれを行う方法の詳細についてはわかりませんが、このテクニックはPaperclipのようなライブラリでうまくいきます。神社では、これはあなたのファイルを参照する直接のShrine::UploadedFileレコードを構築することを意味します。

関連する問題