2013-03-13 3 views
4

J'ai essayé pendant un certain temps de boucher des demandes multipart en utilisant webmock et n'ai pas trouvé une solution satisfaisante.Requêtes multipartites avec webmock/rspec

Idéalement, je voudrais bouchonner la demande comme suit:

stub_request(:post, 'http://test.api.com').with(:body => { :file1 => File.new('filepath1'), file2 => File.new('filepath2') }) 

Cependant, cela ne semble pas fonctionner et RSpec se plaint que la demande n'a pas été bouchonné. La demande non écrasa est imprimé:

stub_request(:post, "http://test.api.com"). 
    with(:body => "--785340\r\nContent-Disposition: form-data; name=\"file1\"; filename=\"filepath1\"\r\nContent-Type: text/plain\r\n\r\nhello\r\n--785340\r\nContent-Disposition: form-data; name=\"file2\"; filename=\"filepath2\"\r\nContent-Type: text/plain\r\n\r\nhello2\r\n--785340\r\n", 
      :headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'Content-Length'=>'664', 'Content-Type'=>'multipart/form-data; boundary=785340', 'User-Agent'=>'Ruby'}). 
    to_return(:status => 200, :body => "", :headers => {}) 

Bien sûr, je ne peux pas vraiment suivre cette suggestion car les limites sont générées dynamiquement. Avez-vous une idée de ce que je pourrais faire pour supprimer ces demandes?

Merci! Bruno

Répondre

2

WebMock ne prend pas en charge les demandes multipart pour le moment. Vérifiez le commentaire de l'auteur ici pour plus d'informations: https://github.com/vcr/vcr/issues/295#issuecomment-20181472

Je vous suggère de considérer l'une des routes suivantes:

  • stubbing sans correspondre au poste corps multipart
  • enveloppant la demande dans une méthode avec des arguments de chemin de fichier et la mise en attente à grain plus fin sur cette méthode
  • avec VCR pour se moquant des demandes externes des tests d'intégration
2

Un peu en retard mais je vais laisser une réponse pour les futurs overflowers et googlers.

J'ai eu le même problème et utilisé Rack::Multipart::Parser en conjonction avec Webmock comme un travail autour. Code rapide et sale devrait ressembler à ceci (avertissement: utilise ActiveSupport extensions):

stub_request(:post, 'sample.com').with do |req| 
    env = req.headers.transform_keys { |key| key.underscore.upcase } 
        .merge('rack.input' => StringIO.new(req.body)) 
    parsed_request = Rack::Multipart::Parser.new(env).parse 

    # Expectations: 
    assert_equal parsed_request["file1"][:tempfile].read, "hello world" 
end 
0

Voici une solution en utilisant WebMock avec regex faire correspondre les demandes multipart/form-data, particulièrement pratique pour tester le téléchargement d'images:

stub_request(:post, 'sample.com').with do |req| 

    # Test the headers. 
    assert_equal req.headers['Accept'], 'application/json' 
    assert_equal req.headers['Accept-Encoding'], 'gzip, deflate' 
    assert_equal req.headers['Content-Length'], 796588 
    assert_match %r{\Amultipart/form-data}, req.headers['Content-Type'] 
    assert_equal req.headers['User-Agent'], 'Ruby' 

    # Test the body. This will exclude the image blob data which follow these lines in the body 
    req.body.lines[1].match('Content-Disposition: form-data; name="FormParameterNameForImage"; filename="image_filename.jpeg"').size >= 1 
    req.body.lines[2].match('Content-Type: img/jpeg').size >= 1 

end 

test uniquement les en-têtes pourraient également avoir été fait en utilisant le chemin de WebMock normale d'utilisation stub_request(:post, 'sample.com').with(headers: {'Accept' => 'application/json}), et tout simplement pas inclure toutes les spécifications du corps dans la clause with.