Topic: Testing Controller Actions

Hello everyone, I was wondering if I could ask a question about something that's driving me crazy. I'm trying to figure out how to run functional tests in rails (currently running 3.2.11, with ruby version 1.9.3-p362). In particular, I'm trying to access variables within the actions (@variables_like_me) in order to test that my programs are producing the results I'm expecting.

The various resources I see out there:
https://www.sit.auckland.ac.nz/Unit_and … _for_Rails
http://www.codethinked.com/rails-3-baby-steps-part-4
http://guides.rubyonrails.org/testing.html

seem to suggest several steps to the process.

You must have a controller
happy_controller.rb:

class Happy_Controller < ApplicationController
  def happy_action
    @test_string = "Hello giant robots!"
  end 
end

and you should have a test within the functional tests folder - prefferably one that ends in _test.rb
happy_controller_test.rb:

require 'test_helper'
#require 'happy_controller' <- tried this but ruby mine is throwing a fit, 
#but the action symbol works fine later so I doubt this is the problem.

class Happy_Controller_Test < ActionController::TestCase
  #This setup seems necessary in a copy pasta mannerism
  def setup
    @controller = Happy_Controller.new
    @request = ActionController::TestRequest.new
    @responce = ActionController::TestResponce.new
  end

  #Then we get to the tests themselves
  #This part works - even though I wonder why simple_cov gave 100% coverage before, but
  #now claims none
  test "should respond when call for the action" do
    get :happy_controller
    assert_responce: :success
  end

  test "should have a variable @test_string = 'Hello giant robots!'" do
    get :happy_controller
    assert_equal("Hello giant robots!", assigns(:test_string))
    #I've also tried assigns(:@test_string) and assigns("test_string") and assigns("@test_string") nothing I try seems to work
  end
end

To this end, I'm beginning to believe the problem has something to do with how this is done in Rails 2 and how its (mysteriously?) now done in Rails 3. Note that I'm starting my tests out with the word 'test' while the examples start out with a method def test_that_does_something_awesome. Now, I would try this (in fact let's) but it still does nothing; it's functional but it declares that the value of the variable is <nil> and not the expected string -- in my case above "Hello giant robots!". On top of that, I'd rather learn to do things the Rails 3 way using tests, although I'm sure everything will change in Rails 4 just to addle my brain further.

For note, when I do try

puts assigns.to_s

my tests declare that the list of variables inside are:

{"_routes"=>nil, "ips"=>["xyz.xyz.xyz.x", "xyz.x.y.a", "xy.xy.xyz.xyz"], "_db_runtime"=>0}

This almost suggests that it's getting nothing back. That's where I've run into a dead end - any ideas?

Thank you in advance.

Sincerely,
Dante83

Re: Testing Controller Actions

Ok, I got 'an' answer - but I don't know if it's THE answer (e.g. it might not be the proper way to make this work... but for now it's my only option so there is no reason to be overly picky).

For future reference and for anyone else who might be struggling with this, I figured I'd post the result. The primary change occurs in the test section above:

require 'test_helper'
#require 'happy_controller' <- tried this but ruby mine is throwing a fit, 
#but the action symbol works fine later so I doubt this is the problem.

class Happy_Controller_Test < ActionController::TestCase
  #This setup seems necessary in a copy pasta mannerism
  def setup
    @controller = Happy_Controller.new
    @request = ActionController::TestRequest.new
    @responce = ActionController::TestResponce.new
  end

  #Then we get to the tests themselves
  #This part works - even though I wonder why simple_cov gave 100% coverage before, but
  #now claims none
  test "should respond when call for the action" do
    get :happy_controller
    assert_responce: :success
  end

  test "should have a variable @test_string = 'Hello giant robots!'" do
    #GET RID OF THIS------------------------------------------
    #get :happy_controller
    #assert_equal("Hello giant robots!", assigns(:test_string))
    #GET RID OF THIS------------------------------------------

    #REPLACE WITH---------------------------------------------
      #Call the class action from the controller that you got above
      @controller.happy_action
      #Now that this method has been fired, you can now access the instance_variables within the controller
      #type in the instance variable you're looking for (preceeded by  :@) and BAM! awesome testable functionality
      assert_equal("Hello giant robots!", @controller.instance_variable_get(:@test_var))
    #REPLACE WITH---------------------------------------------

end

Re: Testing Controller Actions

With your setup, I wasn't even able to execute the tests.  There are abvious typos like "Responce" instead of "Response".  I fixed the setup and ended up with this code:

# app/controllers/happy_controller.rb
class Happy_Controller < ApplicationController
  def happy_action
    @test_string = "Hello giant robots!"
    render :nothing => true # to get rid of 'missing template' errors during tests
  end 
end

# config/routes.rb
Testapp::Application.routes.draw do
  # just to draw any route at all which may work
  match ':controller(/:action(/:id))(.:format)'
end


# test/functional/happy_controller_test.rb
require 'test_helper'

class Happy_Controller_Test < ActionController::TestCase
  def setup
    @controller = Happy_Controller.new
    @request = ActionController::TestRequest.new
    @response = ActionController::TestResponse.new
  end

  test "should respond when call for the action" do
    get 'happy_action'
    assert_response :success
  end

  test "should have a variable @test_string = 'Hello giant robots!'" do
    get 'happy_action'
    assert_equal("Hello giant robots!", assigns(:test_string))
  end
end

Et voilà:

$ rake test
Run options: 

# Running tests:

Finished tests in 0.185072s, 10.8066 tests/s, 10.8066 assertions/s.                                          
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

ruby -v: ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.2.0]

I think there's something wrong with your setup elsewhere.  If you'd like, I could zip this fairly empty project and you try it for yourself.

Last edited by DivineDominion (2013-03-28 04:25:15)