Как убрать библиотеку flickraw в модульных тестах моего приложения? - PullRequest
1 голос
/ 22 августа 2010

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

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

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

Так что мои так называемые юнит-тесты больше похожи на интеграционные тесты.Я понимаю, как написать макет или заглушку с помощью RSpec, но не уверен, как это сделать в библиотеке 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.рб:

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

1 Ответ

0 голосов
/ 12 февраля 2011

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

Можете ли вы изменить реализацию slide так, чтобы вместо загрузки attr_accessors у вас были реальные методы, которые получают данные из API flickr?Вы должны быть в состоянии сделать это без изменения внешнего 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).

...