2010-08-21 26 views
1

L'application My Rails 2 affiche un diaporama de photos de Flickr via la bibliothèque flickraw. Mon code fonctionne, mais je suis bloqué sur comment écrire correctement les tests unitaires RSpec.Comment supprimer la bibliothèque flickraw dans les tests unitaires de mon application?

J'ai une classe Slide qui encapsule tout ce dont mon application a besoin de flickraw. Il agit un peu comme un objet modèle mais n'utilise pas ActiveRecord. Ça ne fait pas beaucoup de travail. il délègue la plus grande partie de la lourde tâche à Flickraw. Je n'ai pas terminé les tests parce que, comme c'est le cas maintenant, ils exigent que je code en dur dans certaines photos de Flickr, et les tests seraient interrompus si je réarrangeais mon photoset si j'ajoutais de nouvelles photos. Donc, mes soi-disant tests unitaires s'apparentent plus à des tests d'intégration. Je comprends comment écrire une maquette ou un bouchon en utilisant RSpec, mais je ne sais pas comment le faire dans la bibliothèque de Flickraw. Comment est-ce que je peux remplacer le flickraw et le transformer en un test unitaire?

slide.rb:

require 'flickraw' 
FlickRaw.api_key = "xxx" 
FlickRaw.shared_secret = "yyy" 
flickr.auth.checkToken :auth_token => "zzz" 
PHOTOSET_ID = 123123123 

class Slide 
    attr_accessor :id, :previous_id, :next_id, :url_square, :url_thumbnail, :url_small, :url_medium500, 
       :url_medium640, :url_large, :url_original 

    def self.last 
    photoset = flickr.photosets.getPhotos(:photoset_id => PHOTOSET_ID) 
    Slide.new(photoset.photo.last.id) 
    end 

    def self.first 
    photoset = flickr.photosets.getPhotos(:photoset_id => PHOTOSET_ID) 
    Slide.new(photoset.photo.first.id) 
    end 

    def self.find(id) 
    Slide.new(id) 
    end 

    def initialize(id) 
    self.id = id 
    photo = flickr.photos.getInfo(:photo_id => id) 
    context = flickr.photosets.getContext(:photoset_id => PHOTOSET_ID, :photo_id => id) 
    sizes = flickr.photos.getSizes(:photo_id => id) 

    self.previous_id = (context.prevphoto.id == 0) ? nil : context.prevphoto.id 
    self.next_id = (context.nextphoto.id == 0) ? nil : context.nextphoto.id 

    sizes.each do |size| 
     if size.label == "Square" 
     self.url_square = size.source 
     elsif size.label == "Thumbnail" 
     self.url_thumbnail = size.source 
     elsif size.label == "Small" 
     self.url_small = size.source 
     elsif size.label == "Medium" 
     self.url_medium500 = size.source 
     elsif size.label == "Medium 640" 
     self.url_medium640 = size.source 
     elsif size.label == "Large" 
     self.url_large = size.source 
     elsif size.label == "Original" 
     self.url_original = size.source 
     end 
    end 
    end 
end 

slide_spec.rb:

require 'spec_helper' 

describe Slide do 
    before(:each) do 
    first_photo_id = "444555666" 
    @slide = Slide.new(first_photo_id) 
    end 

    describe "urls" do 
    it "should generate the thumbnail url" do 
     @slide.url_thumbnail.should match(/_t.jpg$/) 
    end 

    it "should generate the small url" do 
     @slide.url_small.should match(/_m.jpg$/) 
    end 

    it "should generate the medium500 url" do 
     @slide.url_medium500.should match(/.jpg$/) 
    end 

    it "should generate the medium640 url" do 
     @slide.url_medium640.should match(/_z.jpg$/) 
    end 

    it "should generate the large url" do 
     @slide.url_large.should match(/_b.jpg$/) 
    end 

    it "should generate the original url" do 
     @slide.url_original.should match(/_o.jpg$/) 
    end 
    end 

    describe "finding" do 
    it "should find the correct last photo" do 
     # ??? 
    end 

    it "should find the correct first photo" do 
     # ??? 
    end 
    end 

    describe "context" do 
    it "should return the correct previous photo" do 
     # ??? 
    end 

    it "should return the correct next photo" do 
     # ??? 
    end 
    end 
end 

Répondre

0

Si je comprends bien, vous devriez être en mesure de faire slide.stub! (: Flickr) .et_retour de se moquer de tout ce qui n'est pas dans le constructeur. Je m'interroge sur le fait que le constructeur charge beaucoup de l'API Flickr.

Pouvez-vous modifier l'implémentation de la diapositive afin qu'au lieu d'un chargement de attr_accessors, vous ayez des méthodes réelles qui obtiennent des choses de l'API flickr? Vous devriez être capable de le faire sans changer l'API externe de la classe, et vous pouvez activer la vitesse en mettant en cache les résultats des appels API dans les variables d'instance.

Si vous voulez encore faire tout ce travail dans le constructeur, je vous recommande d'avoir un argument par défaut qui représente le service flickr. Votre constructeur devient alors le suivant:

def initialize(id, flickr=flickr) 
    … complicated setup code here… 
end 

De cette façon, lorsque vous testez, juste passer dans un objet mock flickr comme ceci:

flickr = mock(:flickr) 
@slide = Slide.new(image_id, flickr) 

Vous pouvez alors écrire les affirmations rspec habituelles contre la nouvel objet flickr (encore une fois, sans changer l'API externe).