controller_test_case.rb

Path: lib/test/rails/controller_test_case.rb
Last Update: Fri Jul 03 23:57:03 -0600 2009

ControllerTestCase allows controllers to be tested independent of their views.

Features

  • ActionMailer is already set up for you.
  • The session and flash accessors work on both sides of get/post/etc.
  • Optional automatic auditing for missing assert_assigns. See util_audit_assert_assigned

Naming

The test class must be named after your controller class name, so if you‘re testing actions for the RouteController you would name your test case RouteControllerTest.

The test names should be in the form of test_action_edgecase where ‘action’ corresponds to the name of the controller action, and ‘edgecase’ describes the scenario you are testing.

If you are testing an action named ‘show’ your test should be named test_show. If your action behaves differently depending upon its arguments then you can make the test name descriptive like test_show_photos and test_show_no_photos.

Examples

Typical Controller Test

  class RouteControllerTest < Test::Rails::ControllerTestCase

    fixtures :users, :routes, :points, :photos

    def test_delete
      # Store current count
      count = Route.count
      # Set up our environment
      session[:username] = users(:herbert).username

      # perform the delete action
      get :delete, :id => routes(:work).id

      # Assert we got a 200
      assert_response :success
      # Assert controller deleted route
      assert_equal count-1, Route.count
      # Ensure that @action_title is set properly
      assert_assigned :action_title, "Deleting \"#{routes(:work).name}\""
      # Ensure that @route is set properly
      assert_assigned :route, routes(:work)
    end

  end

ActionMailer Test

  class ApplicationController < ActionController::Base

    ##
    # Send an email when we get an unhandled exception.

    def log_error(exception)
      case exception
      when ::ActionController::RoutingError,
           ::ActionController::UnknownAction,
           ::ActiveRecord::RecordNotFound then
        # ignore
      else
        unless RAILS_ENV == 'development' then
          Email.deliver_error exception, params, session, @request.env
        end
      end
    end

  end

  ##
  # Dummy Controller just for testing.

  class DummyController < ApplicationController

    def error
      # Simulate a bug in our application
      raise RuntimeError
    end

  end

  class DummyControllerTest < Test::Rails::ControllerTestCase

    def test_error_email
      # The rescue_action added by ControllerTestCase needs to be removed so
      # that exceptions fall through to the real error handler
      @controller.class.send :remove_method, :rescue_action

      # Fire off a request
      get :error

      # We should get a 500
      assert_response 500

      # And one delivered email
      assert_equal 1, @deliveries.length, 'error email sent'
    end

  end

[Validate]