Notes posted to RSpec

RSS feed
March 4, 2010 - (>= 1.2.8)
0 thanks

stub_chain is very useful when testing controller code

or any other chained method call type that you’d like to stub, example:

in your controller:

   def new
     @user = current_site.users.new
   end

in your spec:

   it "#new should assign a @user" do
     u = mock("User")
     controller.stub_chain(:current_site, :users, :new).and_return(u)
     assigns[:user].should == u
   end

whereas before you had to stub each chained method call separately:

   it "#new should assign a @user" do
     u = mock("User")
     users = mock("Users collection", :new => u)
     site = mock("Site", :users => users)
     controller.stub!(:current_site).and_return(site)
     assigns[:user].should == u
   end

Please note that stub_chain was added to RSpec in version 1.2.6

June 12, 2009
0 thanks

Reusing shared examples

 share_examples_for "a shape" do
    it "should have a color" do
      @shape.color.should == :black
    end
  end

 describe "a circle" do
   before(:all) do
     @shape = Circle.new
   end
   it_should_behave_like "a shape"
 end
June 12, 2009
0 thanks

A stub with argument and return value

 it "should use a dummy method with argument and return value" do
  dummy = mock("dummy").stub!(:emulate)
  dummy.should_receive(:emulate).with(:something).and_return("Done! sir!")
  dummy.emulate(:something).should == "Done! sir!"
 end
June 4, 2009
1 thank

A typical usage for a mock

You want to use a mock when you’re testing a behaviour of one of your methods that interacts with some outside world service (eg. an FTP server).

   it "should login to ftp server" do
     ftp = mock('Ftp server', :null_object => true)
     Net::FTP.should_receive(:new).and_return(ftp)
     ftp.should_receive(:login).with('username', 'password')
     some_obj.connect
   end

   def connect
     session = Net::FTP.new('server.com')
     session.login('username', 'password')
     session.close
   end
June 1, 2009
1 thank

Shared examples

Use it together with share_examples_for like this:

  share_examples_for "a shape" do
    it "should have a color" do
      # ...
    end

    it "should have a center point" do
      # ...
    end
  end

  describe "a circle" do
    it_should_behave_like "a shape"

    it "should be round" do
      # ...
    end
  end
June 1, 2009
0 thanks

Typical stub! usage

Typically you would call

  my_object.stub!(:updated_at).and_return(time_object)
February 17, 2009
4 thanks

Usage examples

Basic usage:

  User.should_receive(:find).with(:all, anything).and_return("hello world")

Now:

  User.find(:all, :conditions => "foo")  #=> "hello world"

But you can also use blocks for more complex matching logic. For example:

  User.should_receive(:find) { |*args|
    if args.size == 2
      "received two arguments"
    else
      "something else"
    end
  }.at_least(:once)

Now:

  User.find(:all, :conditions => "bar")  #=> "received two arguments"
  User.find(5)                           #=> "something else"

Of course normally you’d return mocks instead of strings.

February 4, 2009
0 thanks
February 2, 2009
1 thank

usage

code

 @items = Item.find(:all)
 @items.should have_at_least(1).item
September 27, 2008
3 thanks

Example using simple_matcher

This is extracted from: http://blog.davidchelimsky.net/2008/6/7/thoughts-on-the-dance-off

Here’s an example:

  def be_sorted
    simple_matcher("a sorted list") {|actual| actual.sort == actual}
  end
  [1,2,3].should be_sorted

The block is handed the actual value. If the block returns true, the expectation passes. If it returns false, it fails with the following message:

expected "a sorted list" but got [1, 3, 2]

If you say [1,2,3].should_not be_sorted you’d get this message instead=:

expected not to get "a sorted list", but got [1, 2, 3]

As of now, you don’t get any control over the failure message other than the string you pass to the simple_matcher method

August 15, 2008
8 thanks

anything matcher

The anything matcher will match any ruby object:

  1.should == anything
  nil.should == anything
  'string'.should == anything

  var.should_receive(:method).with(param1, anything)
August 14, 2008
12 thanks

Testing an options hash receives certain parameters

This method is very useful for testing methods that use the ruby idiom of accepting a hash with configurable options.

  class Example
    def self.find(options = {})
      ...
    end
  end

We can use hash_including to ensure that certain options are passed in when mocking it.

  Example.should_receive(:find).with(hash_including(:conditions => 'some conditions'))

  Example.find(:conditions => 'some_conditions', :order => 1)
  # => Passes expectation

  Example.find(:order => 1)
  # => Fails expectation

This can also be used to great effect with the anything matcher. For example:

  hash_including(:key => anything)

  hash_including(anything => 'value')