建立Stub修改对象行为模拟失败

修改spec/models/movie_spec.rb

require 'rails_helper'
require 'spec_helper'

describe Movie do
  describe 'searching Tmdb by keyword' do
    it 'calls Tmdb with title keywords' do
      expect(TmdbMovie).to receive(:find).with('Inception')
      #TmdbMovie.should_receive(:find).with('Inception')
      Movie.find_in_tmdb('Inception')
    end
    it 'should raise an InvalidKeyError with invalid API key' do
      allow(Movie).to receive(:show_exception).and_return(true)
      expect { Movie.find_in_tmdb('Inception') }.to raise_error(Movie::InvalidKeyError)
    end
  end
end

修改app/models/movie.rb,设置一个参数是否抛异常

class Movie < ActiveRecord::Base
  def self.show_exception
      false
  end
  class Movie::InvalidKeyError < StandardError ; end
  def self.find_in_tmdb(string)
    TmdbMovie.find(string)
    rescue NoMethodError => tmdb_gem_exception
    rescue ArgumentError => argument_exception
    rescue TypeError => type_exception
    if self.show_exception
      raise Movie::InvalidKeyError, 'Invalid API key'
    else
      raise tmdb_gem_exception
    end
  end

执行

bundle exec rspec -c  spec/models/movie_spec.rb

进一步Stub模拟失败的行为

require 'rails_helper'
require 'spec_helper'

describe Movie do
  describe 'searching Tmdb by keyword' do
    it 'calls Tmdb with title keywords' do
      expect(TmdbMovie).to receive(:find).with('Inception')
      Movie.find_in_tmdb('Inception')
    end
    it 'should raise an InvalidKeyError with flag set' do
      allow(Movie).to receive(:show_exception).and_return(true)
      expect { Movie.find_in_tmdb('Inception') }.to raise_error(Movie::InvalidKeyError)
    end
    it 'should raise an InvalidKeyError directly' do
      allow(TmdbMovie).to receive(:find).and_raise(Movie::InvalidKeyError.new("test"))
      expect { Movie.find_in_tmdb('Inception') }.to raise_error(Movie::InvalidKeyError)
    end
  end
end

以下代码,让TmdbMovie的find函数直接抛出一个Movie::InvalidKey的异常。

进一步Stub模拟TMDB网站

根据上一节以及前面的演示,我们可以在tmdb不能访问的时候直接返回模拟tmdb的数据,或者更进一步的我们采用FakeWeb模拟一个TMDB的服务器网站