Module: Shoulda::ClassMethods

Included in:
Test::Unit::TestCase
Defined in:
lib/shoulda/context.rb

Instance Method Summary collapse

Instance Method Details

#before_should(name, &blk) ⇒ Object

Before statements

Before statements are should statements that run before the current context’s setup. These are especially useful when setting expectations.

Example:

class UserControllerTest < Test::Unit::TestCase
  context "the index action" do
    setup do
      @users = [Factory(:user)]
      User.stubs(:find).returns(@users)
    end

    context "on GET" do
      setup { get :index }

      should_respond_with :success

      # runs before "get :index"
      before_should "find all users" do
        User.expects(:find).with(:all).returns(@users)
      end
    end
  end
end


98
99
100
# File 'lib/shoulda/context.rb', line 98

def before_should(name, &blk)
  should(name, :before => blk) { assert true }
end

#context(name, &blk) ⇒ Object

Contexts

A context block groups should statements under a common set of setup/teardown methods. Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability and readability of your test code.

A context block can contain setup, should, should_eventually, and teardown blocks.

class UserTest < Test::Unit::TestCase
  context "A User instance" do
    setup do
      @user = User.find(:first)
    end

    should "return its full name"
      assert_equal 'John Doe', @user.full_name
    end
  end
end

This code will produce the method "test: A User instance should return its full name. ".

Contexts may be nested. Nested contexts run their setup blocks from out to in before each should statement. They then run their teardown blocks from in to out after each should statement.

class UserTest < Test::Unit::TestCase
  context "A User instance" do
    setup do
      @user = User.find(:first)
    end

    should "return its full name"
      assert_equal 'John Doe', @user.full_name
    end

    context "with a profile" do
      setup do
        @user.profile = Profile.find(:first)
      end

      should "return true when sent :has_profile?"
        assert @user.has_profile?
      end
    end
  end
end

This code will produce the following methods

  • "test: A User instance should return its full name. "

  • "test: A User instance with a profile should return true when sent :has_profile?. "

Just like should statements, a context block can exist next to normal def test_the_old_way; end tests. This means you do not have to fully commit to the context/should syntax in a test file.



165
166
167
168
169
170
171
172
# File 'lib/shoulda/context.rb', line 165

def context(name, &blk)
  if Shoulda.current_context
    Shoulda.current_context.context(name, &blk)
  else
    context = Shoulda::Context.new(name, self, &blk)
    context.build
  end
end

#described_typeObject

Returns the class being tested, as determined by the test class name.

class UserTest; described_type; end
# => User


178
179
180
# File 'lib/shoulda/context.rb', line 178

def described_type
  self.name.gsub(/Test$/, '').constantize
end

#should(name, options = {}, &blk) ⇒ Object

Should statements

Should statements are just syntactic sugar over normal Test::Unit test methods. A should block contains all the normal code and assertions you’re used to seeing, with the added benefit that they can be wrapped inside context blocks (see below).

Example:

class UserTest < Test::Unit::TestCase

  def setup
    @user = User.new("John", "Doe")
  end

  should "return its full name"
    assert_equal 'John Doe', @user.full_name
  end

end

…will produce the following test:

  • "test: User should return its full name. "

Note: The part before should in the test name is gleamed from the name of the Test::Unit class.

Should statements can also take a Proc as a :before option. This proc runs after any parent context’s setups but before the current context’s setup.

Example:

context "Some context" do
  setup { puts("I run after the :before proc") }

  should "run a :before proc", :before => lambda { puts("I run before the setup") }  do
    assert true
  end
end


60
61
62
63
64
65
66
67
68
69
70
# File 'lib/shoulda/context.rb', line 60

def should(name, options = {}, &blk)
  if Shoulda.current_context
    block_given? ? Shoulda.current_context.should(name, options, &blk) : Shoulda.current_context.should_eventually(name)
  else
    context_name = self.name.gsub(/Test/, "")
    context = Shoulda::Context.new(context_name, self) do
      block_given? ? should(name, options, &blk) : should_eventually(name)
    end
    context.build
  end
end

#should_eventually(name, options = {}, &blk) ⇒ Object

Just like should, but never runs, and instead prints an ‘X’ in the Test::Unit output.



103
104
105
106
107
108
109
# File 'lib/shoulda/context.rb', line 103

def should_eventually(name, options = {}, &blk)
  context_name = self.name.gsub(/Test/, "")
  context = Shoulda::Context.new(context_name, self) do
    should_eventually(name, &blk)
  end
  context.build
end

#subject(&block) ⇒ Object

Sets the return value of the subject instance method:

class UserTest < Test::Unit::TestCase
  subject { User.first }

  # uses the existing user
  should_validate_uniqueness_of :email
end


190
191
192
# File 'lib/shoulda/context.rb', line 190

def subject(&block)
  @subject_block = block
end

#subject_blockObject

:nodoc:



194
195
196
# File 'lib/shoulda/context.rb', line 194

def subject_block # :nodoc:
  @subject_block
end