# Test di un worker con rspec

**URL:** <https://www.ruby-forum.com/t/test-di-un-worker-con-rspec/225603>\
**Category:** IT\
**Created:** [January 17, 2013, 9:26pm UTC](https://www.ruby-forum.com/t/test-di-un-worker-con-rspec/225603 "2013-01-17T21:26:24Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [January 17, 2013, 9:26pm UTC](https://www.ruby-forum.com/t/test-di-un-worker-con-rspec/225603/1 "2013-01-17T21:26:24Z")

</div>

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 🙂

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:in`set\_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:in`request’  
/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:in`perform\_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:in`block 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:in`handle\_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:in`upload’  
/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:in`block (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 🙂  
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.

---

<div class="post-metadata">

**Author:** ![lorenzo\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eb8c5e/32.png) [@lorenzo\_s](https://www.ruby-forum.com/u/lorenzo_s)\
**Post date:** [January 24, 2013, 2:55pm UTC](https://www.ruby-forum.com/t/test-di-un-worker-con-rspec/225603/2 "2013-01-24T14:55:09Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![lorenzo\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eb8c5e/32.png) [@lorenzo\_s](https://www.ruby-forum.com/u/lorenzo_s)\
**Post date:** [January 25, 2013, 9:59am UTC](https://www.ruby-forum.com/t/test-di-un-worker-con-rspec/225603/3 "2013-01-25T09:59:51Z")

</div>

2013/1/24 Riccardo T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

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

Su questo concordiamo 🙂

> 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 😉  
ciao lo
