Test di un worker con rspec

Ciao lista,

sto utilizzando sidekiq, rspec e rails 3.2.11. Vorrei fare un test di
integrazione con un worker che fa un upload di un file su SoundCloud
Devo essere incappato in qualche magia di rails che non colgo :slight_smile:

il blocco di codice da testare:
def upload(audio)

  client = Soundcloud.new({
                              :client_id      =>

APP_CONFIG[:sound_cloud_client_id],
:client_secret =>
APP_CONFIG[:sound_cloud_client_secret],
:access_token =>
APP_CONFIG[:sound_cloud_access_token]
})

  @track = client.post('/tracks', :track => {
      :title        => "[#{Rails.env}] #{audio.id} #{@vm.name}",
      :asset_data   => File.new(audio.file.path(:original)),
      :commentable  => false,
      :sharing => "private"
  })

end

il mio test:

it “should upload an audio” do
#audio = FactoryGirl.create(:audio, :file =>
File.new("#{Rails.root}/spec/fixtures/audio.m4a") )#
Rack::Test::UploadedFile.new( ) )
audio = FactoryGirl.create(:audio, :file =>
Rack::Test::UploadedFile.new( “#{Rails.root}/spec/fixtures/audio.m4a”,
‘audio/m4a’) )
vm = FactoryGirl.create(:vm, :audio_id => audio.id)
track = subject.upload(audio,vm).nil?.should be_false
end

il test fallisce dicendo
Error undefined method `map’ for #String:0x007ff1ec558d28

Dopo un po’ di fatica sono riuscito ad avere il backtrace che da
qualche dettaglio in pi:
— !ruby/exception:NoMethodError
message: !binary |-
dW5kZWZpbmVkIG1ldGhvZCBgbWFwJyBmb3IgIzxTdHJpbmc6MHgwMDdmZjFl
YzU1OGQyOD4=
/Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/httmultiparty-0.3.7/lib/httmultiparty/multipartable.rb:10:in
body=' /Users/lorenzo/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/http.rb:1910:inset_body_internal’
/Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/webmock-1.8.11/lib/webmock/http_lib_adapters/net_http.rb:263:in
request_signature_from_request' /Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/webmock-1.8.11/lib/webmock/http_lib_adapters/net_http.rb:75:inrequest’
/Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/httparty-0.7.8/lib/httparty/request.rb:69:in
perform' /Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/httparty-0.7.8/lib/httparty.rb:390:inperform_request’
/Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/httmultiparty-0.3.7/lib/httmultiparty.rb:81:in
post' /Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/soundcloud-0.2.9/lib/soundcloud.rb:105:inblock in post’
/Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/soundcloud-0.2.9/lib/soundcloud.rb:168:in
call' /Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/soundcloud-0.2.9/lib/soundcloud.rb:168:inhandle_response’
/Users/lorenzo/.rvm/gems/ruby-1.9.3-p194/gems/soundcloud-0.2.9/lib/soundcloud.rb:105:in
post' /Users/lorenzo/Documents/projects/rails/voicemap/app/workers/sound_cloud_worker.rb:32:inupload’
/Users/lorenzo/Documents/projects/rails/voicemap/app/workers/sound_cloud_worker.rb:13:in
perform' /Users/lorenzo/Documents/projects/rails/voicemap/spec/worker/sound_worker_spec.rb:21:inblock (2 levels) in <top (required)>’

Ho capito che il problema come viene gestito :asset_data =>
File.new(audio.file.path(:original))
Se lo tolgo il post viene processato correttamente. Giustamente
soundcloud risponde che manca il file :slight_smile:
Da notare che dentro il controller il mio worker funziona
correttamente. E’ nell’ambiente di test che si schianta.
Ho provato diversi modi di passare il file audio ma non cambia nulla.

Qualche idea? Ho cercato in giro ma con scarsi risultati.

Se ti funzione dal controller vuol dire che il problema e` nel tuo test.
Dal test che hai postato non mi sembra di vedere qualcosa tipo:

worker = Worker.new
worker.perform(file: ‘path’)

se il metodo upload(audio) sta dentro il worker ti consiglio di
nuoverlo:

def perform(track_id)
track = Track.find(track_id)
track.upload
end

track.upload lo testi come qualsiasi perte di rails

2013/1/24 Riccardo T. [email protected]:

Se ti funzione dal controller vuol dire che il problema e` nel tuo test.

Su questo concordiamo :slight_smile:

track.upload
end

Infatti non c’ ma equivalente quello che ho scritto io.
subject.upload o subject.perform vanno scattare lo stesso problema.

Nel frattempo ho capito qualcosa di pi.
L’errore diceva:
“undefined method `map’ for #String:0x007f9ddfe8cd60

Ho indagato sulla riga dello stack
(~/.rvm/gems/ruby-1.9.3-p194/gems/httmultiparty-0.3.7/lib/httmultiparty/multipartable.rb:10)
e in effetti li arriva una stringa anzich un array.
La stringa contiene tutto il body della request. Non ho capito per
dove la stringa non viene convertita in array.

Grazie cmq per la risposta :wink:
ciao lo