2010-08-21 5 views
1

Приложение My Rails 2 отображает слайд-шоу фотографий с Flickr через библиотеку flickraw. Мой код работает, но я зациклился на том, как правильно писать тесты RSpec.Как заполнить библиотеку flickraw в модульных тестах моего приложения?

У меня есть класс Slide, который инкапсулирует все, что нужно моему приложению, из flickraw. Он действует как модельный объект, но не использует ActiveRecord. Это не делает много работы; он делегирует большую часть тяжелого подъема, чтобы щелкнуть.

Я не закончил тесты, потому что, как и сейчас, они требуют от меня жесткого кода на некоторых идентификаторах фотографий от Flickr, и тесты ломаются, если я перестроил свой фотосет или добавил новые фотографии.

Так что мои так называемые модульные тесты больше похожи на интеграционные тесты. Я понимаю, как писать макет или заглушку с помощью RSpec, но не уверен, как это сделать в библиотеке flickraw. Как отключить flickraw и превратить это в единичный тест?

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 

ответ

0

Как я понимаю, вы должны быть в состоянии сделать slide.stub! (: Flickr) .and_return, чтобы издеваться над тем, что находится внутри конструктора. Я запрашиваю тот факт, что конструктор загружает так много от flickr api.

Можете ли вы изменить реализацию слайда, чтобы вместо загрузки attr_accessors у вас были реальные методы, которые извлекали материал из flickr api? Вы должны иметь возможность сделать это, не изменяя внешний api класса, и вы можете включить скорость путем кэширования результатов вызовов api в переменных экземпляра.

Если вы все еще хотите иметь всю эту работу в конструкторе, я бы рекомендовал иметь аргумент по умолчанию, представляющий службу flickr. Ваш конструктор становится следующим:

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

Таким образом, когда вы проверяете, просто передать в макете объекта FLICKR так:

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

Вы можете написать обычный Rspec утверждения по отношению к новый объект flickr (опять же, без изменения внешнего api).