Class: ActionController::IntegrationTest
- Inherits:
-
Test::Unit::TestCase
- Object
- Test::Unit::TestCase
- ActionController::IntegrationTest
- Defined in:
- lib/action_controller/integration.rb
Overview
An IntegrationTest is one that spans multiple controllers and actions, tying them all together to ensure they work together as expected. It tests more completely than either unit or functional tests do, exercising the entire stack, from the dispatcher to the database.
At its simplest, you simply extend IntegrationTest and write your tests using the get/post methods:
require "#{File.dirname(__FILE__)}/test_helper"
require "integration_test"
class ExampleTest < ActionController::IntegrationTest
fixtures :people
def test_login
# get the login page
get "/login"
assert_equal 200, status
# post the login and follow through to the home page
post "/login", :username => people(:jamis).username,
:password => people(:jamis).password
follow_redirect!
assert_equal 200, status
assert_equal "/home", path
end
end
However, you can also have multiple session instances open per test, and even extend those instances with assertions and methods to create a very powerful testing DSL that is specific for your application. You can even reference any named routes you happen to have defined!
require "#{File.dirname(__FILE__)}/test_helper"
require "integration_test"
class AdvancedTest < ActionController::IntegrationTest
fixtures :people, :rooms
def test_login_and_speak
jamis, david = login(:jamis), login(:david)
room = rooms(:office)
jamis.enter(room)
jamis.speak(room, "anybody home?")
david.enter(room)
david.speak(room, "hello!")
end
private
module CustomAssertions
def enter(room)
# reference a named route, for maximum internal consistency!
get(room_url(:id => room.id))
assert(...)
...
end
def speak(room, message)
xml_http_request "/say/#{room.id}", :message => message
assert(...)
...
end
end
def login(who)
open_session do |sess|
sess.extend(CustomAssertions)
who = people(who)
sess.post "/login", :username => who.username,
:password => who.password
assert(...)
end
end
end
Class Method Summary collapse
-
.use_instantiated_fixtures ⇒ Object
:nodoc:.
-
.use_instantiated_fixtures=(flag) ⇒ Object
:nodoc:.
-
.use_transactional_fixtures ⇒ Object
:nodoc:.
-
.use_transactional_fixtures=(flag) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#copy_session_variables! ⇒ Object
Copy the instance variables from the current session instance into the test instance.
-
#initialize(name) ⇒ IntegrationTest
constructor
Work around a bug in test/unit caused by the default test being named as a symbol (:default_test), which causes regex test filters (like “ruby test.rb -n /foo/”) to fail because =~ doesn’t work on symbols.
-
#method_missing(sym, *args, &block) ⇒ Object
Delegate unhandled messages to the current session instance.
-
#open_session {|session| ... } ⇒ Object
Open a new session instance.
-
#reset! ⇒ Object
Reset the current session.
-
#run(*args) ⇒ Object
Work around test/unit’s requirement that every subclass of TestCase have at least one test method.
Methods included from TestProcess
#assigns, #build_request_uri, #cookies, #find_all_tag, #find_tag, #fixture_file_upload, #flash, #follow_redirect, #html_document, included, #process, #redirect_to_url, #session, #with_routing, #xml_http_request
Constructor Details
#initialize(name) ⇒ IntegrationTest
Work around a bug in test/unit caused by the default test being named as a symbol (:default_test), which causes regex test filters (like “ruby test.rb -n /foo/”) to fail because =~ doesn’t work on symbols.
417 418 419 |
# File 'lib/action_controller/integration.rb', line 417 def initialize(name) #:nodoc: super(name.to_s) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object
Delegate unhandled messages to the current session instance.
517 518 519 520 521 522 |
# File 'lib/action_controller/integration.rb', line 517 def method_missing(sym, *args, &block) reset! unless @integration_session returning @integration_session.send(sym, *args, &block) do copy_session_variables! end end |
Class Method Details
.use_instantiated_fixtures ⇒ Object
:nodoc:
454 455 456 457 458 |
# File 'lib/action_controller/integration.rb', line 454 def use_instantiated_fixtures #:nodoc: @_use_instantiated_fixtures ? @use_instantiated_fixtures : superclass.use_instantiated_fixtures end |
.use_instantiated_fixtures=(flag) ⇒ Object
:nodoc:
443 444 445 446 |
# File 'lib/action_controller/integration.rb', line 443 def use_instantiated_fixtures=(flag) #:nodoc: @_use_instantiated_fixtures = true @use_instantiated_fixtures = flag end |
.use_transactional_fixtures ⇒ Object
:nodoc:
448 449 450 451 452 |
# File 'lib/action_controller/integration.rb', line 448 def use_transactional_fixtures #:nodoc: @_use_transactional_fixtures ? @use_transactional_fixtures : superclass.use_transactional_fixtures end |
.use_transactional_fixtures=(flag) ⇒ Object
:nodoc:
438 439 440 441 |
# File 'lib/action_controller/integration.rb', line 438 def use_transactional_fixtures=(flag) #:nodoc: @_use_transactional_fixtures = true @use_transactional_fixtures = flag end |
Instance Method Details
#copy_session_variables! ⇒ Object
Copy the instance variables from the current session instance into the test instance.
509 510 511 512 513 514 |
# File 'lib/action_controller/integration.rb', line 509 def copy_session_variables! #:nodoc: return unless @integration_session %w(controller response request).each do |var| instance_variable_set("@#{var}", @integration_session.send(var)) end end |
#open_session {|session| ... } ⇒ Object
Open a new session instance. If a block is given, the new session is yielded to the block before being returned.
session = open_session do |sess|
sess.extend(CustomAssertions)
end
By default, a single session is automatically created for you, but you can use this method to open multiple sessions that ought to be tested simultaneously.
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
# File 'lib/action_controller/integration.rb', line 486 def open_session session = Integration::Session.new # delegate the fixture accessors back to the test instance extras = Module.new { attr_accessor :delegate, :test_result } self.class.fixture_table_names.each do |table_name| name = table_name.tr(".", "_") next unless respond_to?(name) extras.send(:define_method, name) { |*args| delegate.send(name, *args) } end # delegate add_assertion to the test case extras.send(:define_method, :add_assertion) { test_result.add_assertion } session.extend(extras) session.delegate = self session.test_result = @_result yield session if block_given? session end |
#reset! ⇒ Object
Reset the current session. This is useful for testing multiple sessions in a single test case.
463 464 465 |
# File 'lib/action_controller/integration.rb', line 463 def reset! @integration_session = open_session end |
#run(*args) ⇒ Object
Work around test/unit’s requirement that every subclass of TestCase have at least one test method. Note that this implementation extends to all subclasses, as well, so subclasses of IntegrationTest may also exist without any test methods.
425 426 427 428 |
# File 'lib/action_controller/integration.rb', line 425 def run(*args) #:nodoc: return if @method_name == "default_test" super end |