Module Shoulda::ClassMethods
In: lib/shoulda/context.rb
ValidationMatcher ValidatePresenceOfMatcher ValidateAcceptanceOfMatcher EnsureLengthOfMatcher ValidateFormatOfMatcher EnsureInclusionOfMatcher ValidateUniquenessOfMatcher ValidateNumericalityOfMatcher Context SetSessionMatcher RespondWithContentTypeMatcher SetTheFlashMatcher RenderWithLayout RespondWithMatcher AssignToMatcher FilterParamMatcher RouteMatcher HaveNamedScopeMatcher HaveDbIndexMatcher HaveDbColumnMatcher AllowMassAssignmentOfMatcher AllowValueMatcher AssociationMatcher HaveReadonlyAttributeMatcher lib/shoulda/context.rb lib/shoulda/action_controller/matchers/set_session_matcher.rb lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb lib/shoulda/action_controller/matchers/respond_with_matcher.rb lib/shoulda/action_controller/matchers/assign_to_matcher.rb lib/shoulda/action_controller/matchers/filter_param_matcher.rb lib/shoulda/action_controller/matchers/route_matcher.rb Matchers Macros ActionController lib/shoulda/active_record/matchers/validation_matcher.rb lib/shoulda/active_record/matchers/have_named_scope_matcher.rb lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb lib/shoulda/active_record/matchers/have_db_index_matcher.rb lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb lib/shoulda/active_record/matchers/validate_format_of_matcher.rb lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb lib/shoulda/active_record/matchers/have_db_column_matcher.rb lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb lib/shoulda/active_record/matchers/allow_value_matcher.rb lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb lib/shoulda/active_record/matchers/association_matcher.rb lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb Matchers Helpers Assertions Macros ActiveRecord ClassMethods Macros ActionView Private Helpers Assertions ActionMailer InstanceMethods Assertions Macros Shoulda dot/m_47_0.png

Methods

Public Instance methods

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

[Source]

     # File lib/shoulda/context.rb, line 98
 98:     def before_should(name, &blk)
 99:       should(name, :before => blk) { assert true }
100:     end

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.

[Source]

     # File lib/shoulda/context.rb, line 165
165:     def context(name, &blk)
166:       if Shoulda.current_context
167:         Shoulda.current_context.context(name, &blk)
168:       else
169:         context = Shoulda::Context.new(name, self, &blk)
170:         context.build
171:       end
172:     end

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

  class UserTest; described_type; end
  # => User

[Source]

     # File lib/shoulda/context.rb, line 178
178:     def described_type
179:       self.name.gsub(/Test$/, '').constantize
180:     end

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

[Source]

    # File lib/shoulda/context.rb, line 60
60:     def should(name, options = {}, &blk)
61:       if Shoulda.current_context
62:         block_given? ? Shoulda.current_context.should(name, options, &blk) : Shoulda.current_context.should_eventually(name)
63:       else
64:         context_name = self.name.gsub(/Test/, "")
65:         context = Shoulda::Context.new(context_name, self) do
66:           block_given? ? should(name, options, &blk) : should_eventually(name)
67:         end
68:         context.build
69:       end
70:     end

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

[Source]

     # File lib/shoulda/context.rb, line 103
103:     def should_eventually(name, options = {}, &blk)
104:       context_name = self.name.gsub(/Test/, "")
105:       context = Shoulda::Context.new(context_name, self) do
106:         should_eventually(name, &blk)
107:       end
108:       context.build
109:     end

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

[Source]

     # File lib/shoulda/context.rb, line 190
190:     def subject(&block)
191:       @subject_block = block
192:     end

[Validate]