Blog

Upgrading to RSpec 2 with Ruby on Rails 3

Jonathon Horsman Oct 15 44 comments

Following on from my previous post about upgrading our Rails 2.3.5 application to Rails 3 the most time consuming part was getting our 600 tests passing again.

We use Rspec (upgraded to version 2), Ruby Double (rr) for mocking and Factory Girl.

Here’s the process I followed to get our recently upgraded Rails 3 app working with Rspec 2.

There’s a special place in my heart for the seemingly deliberately terse docs which come with Rspec.

The first 2 lines of the home page says it all:

Overview
Behaviour Driven Development for Ruby.

and that’s it.

Perhaps they’re worried about running out of space on the internet?

Anyway I digress, getting my tests all working again was a bit of a mission.

Update the Gemfile

First the updated Gem versions. At the bottom of my Gemfile they look like this:

group :test do
  gem "rspec"
  gem "rspec-rails"
  gem "autotest"
  #gem "factory_girl", "2.0.0.beta1"
  gem "factory_girl_rails"
  gem "rr"
end

New Spec Helper file

The next step is to update to the new spec_helper.rb file:

ENV["RAILS_ENV"] ||= 'test'

require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'thinking_sphinx/test'

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  # == Mock Framework
  config.mock_with :rr

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  
  ThinkingSphinx::Test.init

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true
end

Broken backwards compatibility

For apparently no good reason there’s a bunch of things which just no longer work.

Sometimes it’s just because they’ve decided to rename the methods.

For instance in all my controller tests I had to do a global search for integrate_views and replace with render_views

Rails params bug

Previously all params in a test get/post/delete/put request would be converted to strings, just as they would appear to your controller in the real world.

However there’s a bug in Rails 3 which means this no longer happens. So where this used to pass:

describe "find contact" do
  before { mock(Contact).find("1234") { Contact.new } } # expect a string for the ID
  describe "successfully" do
    before { get :show { :id => 1234 } } # integer param passed. This used to be converted to a string for me
    it "should render the show view" do
      response.should render_template("show")
    end
  end
end

it now fails with:

unexpected method invocation:
find(1234)
expected invocations:
- find("1234")

I had about 300 of these tests failing and I thought I was going to have to modify every one of them.

Interestingly after digging through the Rails code I found the bug. Evidently this “params massaging” was not deliberately removed because the code is still there. It just overwrites the massaged parameters with the original parameters.

So here’s my fix. Create the file spec/support/action_controller.rb and copy in the content:

module ActionController
  class TestCase < ActiveSupport::TestCase
    module Behavior
      def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
        # Sanity check for required instance variables so we can give an
        # understandable error message.
        %w(@routes @controller @request @response).each do |iv_name|
          if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
            raise "#{iv_name} is nil: make sure you set it in your test's setup method."
          end
        end
        
        @request.recycle!
        @response.recycle!
        @controller.response_body = nil
        @controller.formats = nil
        @controller.params = nil
        
        @html_document = nil
        @request.env['REQUEST_METHOD'] = http_method
        
        parameters ||= {}
        @request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
        
        @request.session = ActionController::TestSession.new(session) unless session.nil?
        @request.session["flash"] = @request.flash.update(flash || {})
        @request.session["flash"].sweep
        
        @controller.request = @request
        #@controller.params.merge!(parameters) # this is the offending line, which I removed
        build_request_uri(action, parameters)
        Base.class_eval { include Testing }
        @controller.process_with_new_base_test(@request, @response)
        @request.session.delete('flash') if @request.session['flash'].blank?
        @response
      end
    end
  end
end

now all those tests should start passing again.

RSpec matchers

A bunch of matchers seem to have been taken out now, but they’re easy enough to roll your own as demonstrated in this video

I wrote the include_text matcher so my old controller tests which look like this will now pass:

response.should include_text('Error: Your update failed')

Yes, this is a view test which doesn’t belong in the controller, but I’m not about to go through all my tests and remove a useful test.

So I created a new file called spec/support/include_text.rb and added this:

module RSpec::Rails
  module Matchers
    RSpec::Matchers.define :include_text do |text|
      match do |response_or_text|
        @content = response_or_text.respond_to?(:body) ? response_or_text.body : response_or_text
        @content.include?(text)
      end

      failure_message_for_should do |text|
        "expected '#{@content}' to contain '#{text}'"
      end

      failure_message_for_should_not do |text|
        "expected #{@content} to not contain '#{text}'"
      end
    end
  end
end

Factory Girl gem change

If you’re using Factory Girl, replace factory_girl in your Gemfile with factory_girl_rails

I don’t know the rationale behind the change but cest la vie.
edit: after looking at the code it appears Factory Girl Rails is just a small wrapper around Factory Girl, so you will still need the Factory Girl gem, probably at version 2.

Assert difference has disappeared

Another useful test method has been inexplicably removed. A complete list of everything which has been removed / renamed would be very useful. I’m looking at you, David Chelimsky

Anyways, to get my assert_difference and assert_no_difference assertions working again, I created the file spec/support/assert_difference.rb:

def assert_difference(executable, how_many = 1, &block)
  before = eval(executable)
  yield
  after = eval(executable)
  after.should == before + how_many
end

def assert_no_difference(executable, &block)
  before = eval(executable)
  yield
  after = eval(executable)
  after.should == before
end

Hey I’m getting closer, down to 72 failures.

Loading files in the lib directory

The ruby files in lib/ are no longer automatically loaded by Rails. So in application.rb I had to add this:

module Matchbook
  class Application < Rails::Application
    require Rails.root.join("lib", "matchbook", "delayed_jobs", "delete_contacts_job.rb")
    require Rails.root.join("lib", "matchbook", "delayed_jobs", "email_creator_job.rb")
    require Rails.root.join("lib", "matchbook", "auditing", "contact_audit_sweeper.rb")

    ...
  end
end

More Rspec pain

I also get a few of these errors:

     unexpected method invocation:
       valid?(nil)
     expected invocations:
     - valid?()

Come on, why aren’t they treated as equivalent now?
Well since there’s only a few of them I went and manually added the nil parameter.

Action Mailer changes

According to the docs ActionMailer methods always return objects, not strings:

Every object in a Mail object returns an object, never a string. So Mail.body returns a Mail::Body class object, need to call encoded or decoded to get the string you want.

So where these tests used to pass

    mail = SiteMailer.email(message, contact, {"message" => message_link, "image" => image_link, "promo" => promo_link})
    
    mail.body.should include_text(message_link.to_s)
    mail.body.should include_text(image_link.to_s)
    mail.body.should include_text(promo_link.to_s)

they now fail. That’s easily fixed with:

    mail = SiteMailer.email(message, contact, {"message" => message_link, "image" => image_link, "promo" => promo_link})

    body = mail.body.encoded.gsub(/=\r\n/, "")
    body.should include_text(message_link.to_s)
    body.should include_text(image_link.to_s)
    body.should include_text(promo_link.to_s)

Note I updated the SiteMailer code to work with the new Rails mailer API. Info in the guide.

Ruby Double mocking with deprecations

This no longer works:

any_instance_of(Note, :validate => nil)

and also produces deprecation warnings. This isn’t the correct rr syntax anyway, so I replaced it with

stub.any_instance_of(Note).valid?(nil) { true }

Display the full stacktrace

Run specs with the -b option to include the full backtrace, rather than just the subset which includes your code.

This is useful for identifying problems in libraries and dependencies.

All tests passing

With some further code changes to work with the new Mail API, fixes to rename a reserved word (field is a no-no column name now) and a couple of other bits and pieces, all 613 of my tests now pass!

Comments //

David Chelimsky

David Chelimsky Oct 20

I'll update the docs with things you've cited that are actually missing, but most of this information is actually readily available. Please read the following and update your post accordingly:

1. http://rspec.info - "More Information" (links to RSpec-2 documentation).

2. http://github.com/rspec/rspec-rails (README - linked from http://rspec.info).

3. http://github.com/rspec/rspec-rails/blob/master/Upgrade.markdown

Additional notes:

a. `assert_difference` is a Rails assertion. RSpec's `should change` is still available and at your disposal.

b. you're using RR for mocking. That's what is providing failure messages about invocations with or without nil.

Hope this helps you and your readers.

Cheers,
David

Kurt Snyder

Kurt Snyder Feb 01

There's a cheat sheet of RSpec1 to RSpec2 changes here: http://snyderscribbles.blogspot.com/2011/01/rspec-2-changes-from-rspec-1.html I'll post additions/corrections that anyone wants to submit.

Kimlueng

Kimlueng Sep 14

Thanks for the pointer. That'll help if I need to conrvet anything else. I'm impressed by how much Rspec has changed in just the last couple of months. I think the older release I was working from dates back only as far as the start of April.

chinacheng

chinacheng Feb 22

i think the assert_difference method could be more better, for example: executable maybe a array

Discount Codes UK

Discount Codes UK Oct 19

Hurrah! Finally I got a weblog from where I know how to truly obtain helpful facts concerning my study and knowledge.

ImminsRaisk

ImminsRaisk Nov 28

唆している。 一つには、親と子は同じ興味を共有することはでき <a href=http://www.africa-divine-safaris.com/%E3%82%B5%E3%83%B3%E3%82%B0%E3%83%A9%E3%82%B9-c-11.html>シャネル サングラス 人気</a> ットレタリングを使用したり、あなたの基本的な招待状に滑らかに <a href=http://www.alnebrasgames.com/%E3%83%9E%E3%83%95%E3%83%A9%E3%83%BC-c-35.html>マフラー</a> いキャリアの見通しを活用することができます。 入手可能な最新 <a href=http://www.bvlgariperfumejp.com/%E3%83%96%E3%83%AB%E3%82%AC%E3%83%AA%E9%A6%99%E6%B0%B4%E3%83%AC%E3%83%87%E3%82%A3%E3%83%BC%E3%82%B9-c-1.html>香水 おすすめ</a> う。

 単一の株式仲買人は、よくやった - 辛うじて <a href=http://www.djbrixx.com/category-10.html>ダウンジャケット モンクレール</a> めに静かな雰囲気を提供しています。

 占星術の歴史は文 <a href=http://www.gyikom.com/category-3.html>グッチの財布</a> デートは、あなたの途方もない空想を共有し、探求して自由であるです。 あなたは間違いなくあなたがcriminals.Bac

enetaTubinake

enetaTubinake Nov 28

く作成されたクジャンは地元の美術館で見ることができるように有 <a href=http://viewdesigncompany.com/news/moncler.php>モンクレール ワンピース</a>
 私たちはただ、時々、彼らは本当にpopular.Soい <a href=http://www.aboveboardadvisors.com/%E3%83%AD%E3%83%AC%E3%83%83%E3%82%AF%E3%82%B9-c-28.html>ロレックス ブログ</a> 1、ビジネス客のためにB2、学生ビザのようなビザの他のタイプ <a href=http://www.broerwenang.com/%E3%83%8D%E3%82%AF%E3%82%BF%E3%82%A4-c-19.html>ネクタイ 結び方</a> 特に、ほとんどの黒の女性は非常に性的である。 ステレオタイ <a href=http://www.dedicatedserver411.com/%E3%82%BB%E3%82%A4%E3%82%B3%E3%83%BC5-%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%84-c-4.html>セイコー5 日本製</a> ます。

 試験が終了するまで、彼らは定期的な生活を続け <a href=http://www.latinabarbie.net/%E3%83%A2%E3%83%B3%E3%82%AF%E3%83%AC%E3%83%BC%E3%83%AB%E3%83%A1%E3%83%B3%E3%82%BA%E3%83%99%E3%82%B9%E3%83%88-c-6.html>モンクレール ダウン 2014 メンズ</a> ンテキストに理論を入れて学生に教室の範囲外で勉強する機会を与ョブを実行する能力と意欲を示してグリーンカードを得ることがで

ImminsRaisk

ImminsRaisk Nov 28

新しいモデル車は、売りにもだが、入札はsoon.Smallビ <a href=http://bibelos.com/>スープラ</a> うに彼の下の大理石の台座に扱われます。 彼のプロポーションは <a href=http://www.als-risk.com/%E3%83%97%E3%83%A9%E3%83%80-%E3%83%9D%E3%83%BC%E3%83%81-c-1.html>プラダ ポーチ 2013</a> の財布の内側に到達し、感電する危険にしたくないので、必ず安全 <a href=http://www.burberrywholesale.com/%E3%83%90%E3%83%BC%E3%83%90%E3%83%AA%E3%83%BC%E3%83%AD%E3%83%B3%E3%83%89%E3%83%B3--c-15.html>バーバリーロンドン ネクタイ</a> 親族を探しすべき? 家系図の名前、あなたは国家重要な記録の系 <a href=http://www.fgjxmk.com/>mcm 激安</a> ないことを何かでなければなりません 予算を決めることです。
<a href=http://www.stabnsplash.com/jp/category/l4_12.html>ダウン/ダウンジャケット</a> 特権。 カリフォルニアの逮捕情報の要求はサクラメント、カリフもしれないが後はそのはるかに良い人生になります。 あなたのポ

UGGS On Sale

UGGS On Sale Dec 03

Because the admin of this web site is working, no hesitation very soon it will be famous, due to its feature contents.

vigrx oil price

vigrx oil price Mar 19

Very good post! We are linking to this particularly great article
on our site. Keep up the great writing.

コピーブランド

コピーブランド Apr 14

buranndofukuはガガミラノ コピー:http://www.buranndofuku.com/gallery-163-grid.html
 日本でも広く流通してしまっているモンクレール 偽物通販店です。
 商品の見分け方や 注意点について紹介しています。
 クロムハーツ 激安の商品特に大人気のクロムハーツ激安 ,クロムハーツ ブランド偽物 格安の種類を豊富に取り揃えます。スーパーコピーブランド:http://www.buranndofuku.com/のお求めはぜひ当店へ!
[url=http://www.buranndofuku.com/gallery-181-grid.html]コピーブランド[/url]

money Network bank of america

money Network bank of america Apr 30

I think this is among the most vital information for me. And i
am glad reading your article. But wanna remark on
few general things, The website style is perfect, the articles
is really great : D. Good job, cheers

http://marseille-tonight.com

http://marseille-tonight.com May 03

Wonderful beat ! I wish to apprentice even as you amend your website, how can i subscribe for
a blog web site? The account aided me a applicable deal.
I were a little bit familiar of this your broadcast offered brilliant clear idea

copy paste cash system scam

copy paste cash system scam May 15

It's genuinely very complex in this busy life to listen news on TV, thus I just use web
for that reason, and obtain the hottest news.

Deandre

Deandre Jun 17

I have read so many content concerning the blogger lovers however this post is truly a pleasant piece of writing, keep it up.

success coach

success coach Jun 24

Marvelous, what a web site it is! This website provides valuable information to us, keep it up.

Angelita

Angelita Jun 25

Hi! I could have sworn I've visited this site before but after going through a
few of the articles I realized it's new to me.
Anyways, I'm definitely pleased I found it and I'll be bookmarking it and checking
back regularly!

delray beach summer youth programs

delray beach summer youth programs Jul 01

The arcade games, adventure and fantasy games can really broaden the children's
minds, show them new worlds, and even help them develop their fantasies.
It should take care of your expenditures on food and lodging for the whole camp.
" Make sure you have a phone or portable radio that you can use to contact someone for help. First thing that you should remember is whether your child should attend a day camp or residential camp. Patrick's Day, Camp Bow Wow has announced that several participating camps will celebrate "Lucky Dogs Go To Camp" week March 12-17. You do not need to worry about your child as he is in safe hands. Where is the camp located, and what are the facilities like. It may have had its beginning in rural America, but these days, 4-H offers activities as diverse as rock climbing, ecology, cooking, forestry, citizenship, animal care and more. So when they put their heart and soul in this course they will not only learn about the particular subject but they will also attain mental growth, which helps them in the long run. We have the gear you need for cross country skiing.

little black bodycon dress

little black bodycon dress Jul 18

Besides of being the field of fashion, you may also
prepare the costly expenses of the profession you may want to take on.
Resources may grace with your presence to related
topics, such as grooming, fashion, and etiquette and not just fashion modeling
alone. Being a model requires more than just being a pretty face.

http://yuki.alinggo.net/

http://yuki.alinggo.net/ Jul 19

Hello there, just became alert to your blog through Google, and
found that it is really informative. I'm going to watch out for
brussels. I'll appreciate if you continue this in future.

Numerous people will be benefited from your writing.

Cheers!

www.google.ca

www.google.ca Jul 25

Yesterday, while I was at work, my sister stole my iphone and
tested to see if it can survive a 40 foot drop, just so she can be a youtube
sensation. My apple ipad is now broken and she has 83 views.
I know this is entirely off topic but I had to share it with someone!

weight loss using hcg

weight loss using hcg Aug 13

The first week, you get acquainted with your new routine, and the end of the diet seems so far away.
Don't let yourself be baffled, acquiring benefits on the <. The treatment comes in both drops and injections, which are given by a doctor.

skin care products ranking

skin care products ranking Aug 15

Testosterone is converted to dihydrotestosterone (DHT) which slows down or stops hair
growth and produces weaker, shorter hair. These shampoo ingredients strip my hair of its oils, which is
overkill since my hair is already dry. If your hair is long and strong, you can go for any kind of style that
suits your face or personality the best.

storage in upper manhattan

storage in upper manhattan Aug 16

Louis, Missouri, and maintains a network of 1,000 affiliated agencies in 135 countries around the world.
Some of the heavy stuffs like piano create real problem for
the removers. Using a yacht delivery service is a simple decision for sea-crossings, but what about moving a
motor yacht interstate from say Sydney to Brisbane or San Francisco to Los Angeles.

Peter

Peter Aug 16

I do trust all of the ideas you have presented for your
post. They are very convincing and can definitely work.

Nonetheless, the posts are too quick for beginners.
May just you please lengthen them a bit from subsequent time?
Thank you for the post.

Low Laser Light Therapy

Low Laser Light Therapy Aug 16

Hair removal in some areas is essential to replace the areas where its growth has stopped.
main light based permanent hair removal technique for men. However,
pulling on a scab that was adherent to the skin usually dislodged the graft - often several days after pulling on a hair was safe.

moving home storage costs

moving home storage costs Aug 16

It is therefore necessary to hire a reputed moving service provider who has high quality vehicles and equipments
for packing, loading and unloading your items.

In house moving services include rearranging
furniture, hanging or repositioning of art or antiques,
clear space for an event or a party or maximising
the potential of the home. Now you need to look for companies that
include as many services as you need to make
your move completed.

social media marketing quote template

social media marketing quote template Aug 19

Most Internet marketers are looking for a "get rich quick" solution for their problems, and they come into this industry without
learning the basics. Constantly run 2 ads on Adwords for every ad group.
But other than those who just want to communicate with
friends, old and new, social media is also currently being taken advantage by business oriented
people as a way to reach their target clients and improve their businesses.

nose job az

nose job az Aug 19

To keep you in the most comfortable and peaceful
state of mind possible, Dr. Nathan Newman is world
renowned for his advanced cosmetic surgery procedures.
You also need to think about the recovery process and the ways
it might affect your daily life and work.

Las Vegas GE Appliance Repair

Las Vegas GE Appliance Repair Aug 19

You can certainly see your enthusiasm in the work you write.
Thhe arena hopes for more passionate writers lioke you who aren't afraid tto say how they believe.
At all times ggo after your heart.

www.honoe.com

www.honoe.com Aug 21

http://www.fukushow.cn 激安 ブランド<a href="http://www.fukushow.cn" target="_blank">激安 ブランド</a>

laser cap for telogen effluvium

laser cap for telogen effluvium Aug 21

This herbal solution will help you achieve picture perfect hair once more.
These use a number of techniques to move the natural oils
down their hair such as boar bristle brushing
and 'scritching' between washes. We live in a climate that gets hot
and humid and there are many activities to choose from.

storage companies in maryland

storage companies in maryland Aug 22

Check out Movers review, it'll assist you simply slim down the alternatives then choose many sensible movers.
These companies have professional staff which carried your goods from one
place to another. The expense apart from covering the vehicle also involves
in spending for the moving boxes.

toilet computer repair pompano beach fl

toilet computer repair pompano beach fl Aug 23

However, if you are remodeling your kitchen, you should preserve the originality of your kitchen and only apply essential components from
the new layout that you have picked, this kind of as only including stools but trying
to keep other things, or maybe only rearranging the placement of the components
of the existing island. You should also allow
a minimum of 36 inches of counter space to the right and then 30
inches to the left of the range and sink, if possible.
Basic Project Control and Communication Plan: The project control component explains the tools that will be used to
assist the project manager in tracking the
project's progress.

howard schwartz cpa esq boca raton florida

howard schwartz cpa esq boca raton florida Aug 23

companies, understanding its accounting laws is necessary.
What the CPA companies want to basically know is your internet experience and how you are going to
send traffic to the CPA offer. Many taxpayers choose
to contact TAS because they are dealing with
a tax debt.

dock box 426 gas timex ironman shock 30 lap

dock box 426 gas timex ironman shock 30 lap Aug 24

She has a charm that is slightly reminiscent of the childhood favourite Rosie and Jim's Ragdoll, with a modernized interior to suit the 21st century traveller.
Leave your windows open a few hours a day and then you get to clean the
black soot off of the floors. But have you ever thought about living in your boat full time.

chloe flint creek

chloe flint creek Aug 25

Because we got so used with it, sun no longer is seen as a threat.

According to a study conducted in a Japanese village, vitamin A present in these eatables make them stay young and live longer.
People have very different types of skin, and the self tanning products you use will look different depending on this.

make money online

make money online Aug 28

Be seen by those searching for you online by being represented on the
first page of major and local search engines. Through a process of analyzing the inbound links into your
site, you can see if they look legitimate or not, and
if they are not then you can tell Google not to count them.
SEO (search engine optimization) is a term that is freely bandied about by people who like to make the
art of internet marketing seem mysterious.

storage units in brooklyn ny 11206

storage units in brooklyn ny 11206 Aug 29

He was separated About 10 months when we started dating and he had confessed to having a crush
on me for a really long time. You can assume from this that they take themselves seriously and you can probably do the same too.
Get help from your pals who've by now hired the movers.

phone 6 release date

phone 6 release date Aug 29

Wow, that's what I was looking for, what a data! present here
at this website, thanks admin of this site.

domain

domain Aug 30

Remarkable things here. I am very happy to see your article.
Thanks so much and I'm taking a look ahead to touch you.
Will you please drop me a e-mail?

medical lawyer

medical lawyer Aug 30

Excellent post. I was checking constantly this blog and I am impressed!
Extremely helpful information particularly the last part :
) I care for such information much. I was looking for this
particular info for a long time. Thank you and best of luck.

corporate gifts customized

corporate gifts customized Aug 31

Hmm is anyone else encountering problems with the images on this blog loading?
I'm trying to find out if its a problem on my end or if it's the
blog. Any feed-back would be greatly appreciated.

boca raton social media marketing business

boca raton social media marketing business Aug 31

Women's magazines are filled with time-saving tips that apply to every
area of our lives. As I said above, I think Traffic Travis is
a great bit of kit. Innovative methods are devised every other day for everything.

Comments are closed

Recent Tweets

Blog: The monumental Myspace cock-up: http://bit.ly/emgRKV
Tweeted on Friday at 09:43

Awww railsapi, delete some logs: http://bit.ly/htBNDH
Tweeted on Wednesday at 16:15