rspec - रेल का उपयोग करके फ़ाइल अपलोड का परीक्षण करें


142

मैं एक फ़ाइल अपलोड रेल का परीक्षण करना चाहता हूं, लेकिन यह सुनिश्चित नहीं है कि यह कैसे करना है।

यहाँ नियंत्रक कोड है:

def uploadLicense
    #Create the license object
    @license = License.create(params[:license]) 


    #Get Session ID
    sessid = session[:session_id]

    puts "\n\nSession_id:\n#{sessid}\n"

    #Generate a random string
    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
    newpass = ""
    1.upto(5) { |i| newpass << chars[rand(chars.size-1)] }

    #Get the original file name
    upload=params[:upload]
    name =  upload['datafile'].original_filename 

    @license.format = File.extname(name)

    #calculate license ID and location
    @license.location = './public/licenses/' + sessid + newpass + name 

    #Save the license file
    #Fileupload.save(params[:upload], @license.location) 
    File.open(@license.location, "wb") { |f| f.write(upload['datafile'].read) }

     #Set license ID
    @license.license_id = sessid + newpass

    #Save the license
    @license.save

    redirect_to :action => 'show', :id => @license.id 
end

मैंने इस युक्ति की कोशिश की है, लेकिन यह काम नहीं करता है:

it "can upload a license and download a license" do
    file = File.new(Rails.root + 'app/controllers/lic.xml')
    license = HashWithIndifferentAccess.new
    license[:datafile] = file
    info = {:id => 4}
    post :uploadLicense, {:license => info, :upload => license}
end

Rspec का उपयोग करके मैं फ़ाइल अपलोड का अनुकरण कैसे कर सकता हूं?

जवाबों:


291

फ़ाइल अपलोडिंग का परीक्षण करने के लिए आप fixture_file_upload पद्धति का उपयोग कर सकते हैं : अपनी परीक्षण फ़ाइल को "{Rails.root} / युक्ति / जुड़नार / फ़ाइलों" निर्देशिका में डालें

before :each do
  @file = fixture_file_upload('files/test_lic.xml', 'text/xml')
end

it "can upload a license" do
  post :uploadLicense, :upload => @file
  response.should be_success
end

मामले में आप फाइल को '' अपलोड '' [] 'डेटाफाइल' के रूप में देख रहे थे।

it "can upload a license" do
  file = Hash.new
  file['datafile'] = @file
  post :uploadLicense, :upload => file
  response.should be_success
end

8
इसे उत्तर के रूप में चिह्नित किया जाना चाहिए, क्योंकि यह सही है। धन्यवाद दोस्त!
एमिल अहलबैक

30
अगर आपको फ़ाइल नहीं मिल रही है तो त्रुटियों के लिए bit.ly/OSrL7R (स्टैक ओवरफ्लो प्रश्न 3966263) देखें । रेल 3.2 में एक अलग रूप की आवश्यकता है: @file = रैक :: टेस्ट :: UploadedFile.new (Rails.root.join ('कल्पना / जुड़नार / फाइलें / test.csv'), 'पाठ / सीएसवी')
माइक बेलीथ

3
यदि आप फ़ाइल के लिए पूर्ण पथ निर्दिष्ट करते हैं, तो fixture_file_upload भी काम करता है: "Rails.root.join ('कल्पना / जुड़नार / फ़ाइलें / test.csv"
jmanrubia

1
fixture_file_upload को परमेस में एक स्ट्रिंग के रूप में माना जा रहा है, किसी को भी पता है क्यों?
अबे पेट्रिलो

3
@AbePetrillo (या जो कोई टिप्पणी देखता है और एक ही सवाल है) मेरे पास एक ही मुद्दा था। मेरे मामले में, पहला तर्क postएक पथ सहायक विधि था, जिसका एकमात्र इरादा तर्क मैंने कोष्ठक में संलग्न नहीं किया था, इसलिए निम्न टोकन को पोस्ट के लिए args के बजाय सहायक के लिए अतिरिक्त args के रूप में व्याख्या किया गया था। जैसे, मेरे post order_documents_path @order, document: fileबजाय था post order_documents_path(@order), document: file
सूपडॉग

54

मुझे यकीन नहीं है कि आप अकेले RSpec का उपयोग करके फ़ाइल अपलोड का परीक्षण कर सकते हैं। क्या आपने Capybara की कोशिश की है ?

attach_fileएक अनुरोध युक्ति से कैपिबारा की विधि का उपयोग करके फ़ाइल अपलोड का परीक्षण करना आसान है ।

उदाहरण के लिए (यह कोड केवल एक डेमो है):

it "can upload a license" do
  visit upload_license_path
  attach_file "uploadLicense", /path/to/file/to/upload
  click_button "Upload License"
end

it "can download an uploaded license" do
  visit license_path
  click_link "Download Uploaded License"
  page.should have_content("Uploaded License")
end

6
बेशक यह एक एकीकरण युक्ति में काम करता है। ओपी का सवाल एक नियंत्रक इकाई युक्ति से संबंधित है, यह देखते हुए कि वह केवल नियंत्रक कोड पोस्ट कर रहा है। किसी के भ्रमित होने पर सिर्फ इतना कहना। एक फ़ीचर स्पेक में ऐसा करें, एक यूनिट स्पेक में ebsbk का उत्तर दें।
स्टार्कर

2
फ़ाइल पथ को उद्धरण चिह्नों में होना चाहिए
साठवाँ

32

यदि आप रैक :: टेस्ट * शामिल करते हैं, तो बस परीक्षण विधियों को शामिल करें

describe "my test set" do
  include Rack::Test::Methods

तो आप UploadedFile विधि का उपयोग कर सकते हैं:

post "/upload/", "file" => Rack::Test::UploadedFile.new("path/to/file.ext", "mime/type")

* नोट: मेरा उदाहरण सिनात्रा पर आधारित है, जो रैक का विस्तार करता है, लेकिन रेल के साथ काम करना चाहिए, जिसमें रैक, टीटीबीओएमके का भी उपयोग होता है


3
FYI करें: जरूरी नहीं कि आप include Rack::Test::Methodsरैक :: टेस्ट :: UploadedFile का उपयोग करें। require 'rack/testपर्याप्त है।
xentek

3
मैं भी नहीं है require 'rack/test'। यदि आप इसका उपयोग कर रहे हैं तो Rack::Test::UploadedFileइसका उपयोग करना काफी अच्छा है। बशर्ते आपके रेल एप्लिकेशन सेटअप ठीक है। पुनश्च: मैं हूँ Rails 4औरruby 2.1
विष्णु नारंग

विष्णु की टिप्पणी सबसे सटीक है, क्योंकि उन्हें स्पष्ट रूप से विधि की आवश्यकता है। शामिल करने rack/testमें परीक्षण से सब कुछ शामिल होगा, जिसमें शामिल हैं test/methods, लेकिन परीक्षण में सब कुछ भी शामिल है , इसलिए शायद आपकी ज़रूरत से ज़्यादा।
zedd45

18

मैंने RSpec का उपयोग करके ऐसा नहीं किया है, लेकिन मेरे पास एक टेस्ट :: यूनिट टेस्ट है जो एक फोटो अपलोड करने के लिए कुछ समान है। मैंने अपलोड की गई फ़ाइल को ActionDispatch के उदाहरण के रूप में सेट किया है :: Http :: UploadedFile, निम्नानुसार:

test "should create photo" do
  setup_file_upload
  assert_difference('Photo.count') do
    post :create, :photo => @photo.attributes
  end
  assert_redirected_to photo_path(assigns(:photo))
end


def setup_file_upload
  test_photo = ActionDispatch::Http::UploadedFile.new({
    :filename => 'test_photo_1.jpg',
    :type => 'image/jpeg',
    :tempfile => File.new("#{Rails.root}/test/fixtures/files/test_photo_1.jpg")
  })
  @photo = Photo.new(
    :title => 'Uploaded photo', 
    :description => 'Uploaded photo description', 
    :filename => test_photo, 
    :public => true)
end

आपके लिए भी कुछ इसी तरह का काम हो सकता है।


6

यह है कि मैंने इसे कैसे किया Rails 6, RSpecऔरRack::Test::UploadedFile

describe 'POST /create' do
  it 'responds with success' do
    post :create, params: {
      license: {
        picture: Rack::Test::UploadedFile.new("#{Rails.root}/spec/fixtures/test-pic.png"),
        name: 'test'
      }
    }

    expect(response).to be_successful
  end
end

ActionDispatch::TestProcessजब तक आप जो भी शामिल हैं उसके बारे में निश्चित नहीं हैं, तब तक शामिल न करें या कोई अन्य कोड न डालें।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.