SitePoint Sponsor

User Tag List

Results 1 to 10 of 10

Hybrid View

  1. #1
    SitePoint Member
    Join Date
    Nov 2005
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    functional testing -- using post() w/ a different controller

    Hallo -- I have a function in test_helper.rb that looks not a little
    like this:

    def
    login(username="gowondapiddlehead",unhashed_password="gowonda_piddlehead")
    postlogin,:system_user=>{:username=>username,:unhashed_password=>unhashed_password})
    assert_redirected_tocontroller=>'home')
    assert_not_nil(session[:system_user_id])
    system_user=SystemUser.find(session[:system_user_id])
    assert_equal(username,system_user.username,"Login name should match
    session name.")
    end

    When I run the test, however, I get the following error:

    1) Error:
    test_index(HomeControllerTest):
    NoMethodError: undefined method `login' for Test::Unit::TestCase:Class
    test/functional/home_controller_test.rb:18:in `test_index'

    I guess this is because I need to specify the controller being called as
    well as the action in the post() function.
    Does anyone know how to do this?
    Cheers,
    doug.

  2. #2
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No, the reason is that its not finding your login() method in your test class. Did you put the login() method inside the

    Code:
    class Test::Unit::TestCase
    ...
    end
    part of your test_helper.rb file?

  3. #3
    SitePoint Member
    Join Date
    Nov 2005
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes -- the full file looks like this:
    Code:
    ENV["RAILS_ENV"] = "test"
    
    # Expand the path to environment so that Ruby does not load it multiple times
    # File.expand_path can be removed if Ruby 1.9 is in use.
    require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
    require 'application'
    
    require 'test/unit'
    require 'active_record/fixtures'
    require 'action_controller/test_process'
    require 'action_web_service/test_invoke'
    require 'breakpoint'
    
    Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
    
    class Test::Unit::TestCase
      # Turn these on to use transactional fixtures with table_name(:fixture_name) instantiation of fixtures
      # self.use_transactional_fixtures = true
      # self.use_instantiated_fixtures  = false
    
      def create_fixtures(*table_names)
        Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures", table_names)
      end
    
      # Add more helper methods to be used by all tests here...
      
      def login(username="gowondapiddlehead",unhashed_password="gowonda_piddlehead")
        post(:login,:system_user=>{:controller=>'login',:username=>username,:unhashed_password=>unhashed_password})
        assert_redirected_to(:controller=>'home')
        assert_not_nil(session[:system_user_id])
        system_user=SystemUser.find(session[:system_user_id])
        assert_equal(username,system_user.username,"Login name should match session name.")
      end
      
    end
    I thought it might be that, but couldn't see any way it wouldn't be seeing the function.
    Cheers,
    doug.

  4. #4
    SitePoint Member
    Join Date
    Nov 2005
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Actually, the error *now* reads:
    Code:
      1) Error:
    test_index(HomeControllerTest):
    ActionController::UnknownAction: No action responded to login
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/filter
    s.rb:295:in `perform_action_without_benchmark'
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/benchm
    arking.rb:41:in `perform_action_without_rescue'
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/benchm
    arking.rb:41:in `measure'
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/benchm
    arking.rb:41:in `perform_action_without_rescue'
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/rescue
    .rb:80:in `perform_action'
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/base.r
    b:356:in `send'
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/base.r
    b:356:in `process'
        c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/test_p
    rocess.rb:275:in `process'
        (eval):3:in `post'
        ./test/functional/../test_helper.rb:28:in `login'
        test/functional/home_controller_test.rb:18:in `test_index'
    -- I've been playing around with the code somewhat!

    doug.

  5. #5
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, yes, you should change:

    Code:
    post(:login...
    to

    Code:
    post(:controller => 'something', :action => 'login'...
    Also, its somewhat of a Rails convention to not use brackets around your method arguments in a lot of cases. Have a look here:

    http://www.rubygarden.org/ruby?RubyStyleGuide

    Also, if you want to simulate a logged in user for the purpose of testing actions that require login, instead of calling your login action (which would be tested elsewhere), simulate the login manually (e.g. if your login action stores the logged in user id in the session, then create this manually by doing `@request.session[:user_id] = 1 or whatever).

  6. #6
    SitePoint Member
    Join Date
    Nov 2005
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cheers man -- for the help, the hints & the style guide, too -- I've been looking for something like that!
    Thanks again,
    doug.

  7. #7
    SitePoint Member
    Join Date
    Dec 2005
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Above advice doesn't seem to work

    postcontroller => 'something', :action => 'login'...

    gives errors of:

    ActionController::UnknownAction: No action responded to actionlogincontrollersomething

    I also tried putting the controller as a variable in the parameters hash:

    post 'login_action', {:controller=>'something'}

    But it doesn't invoke controller 'something', rather it invokes whatever the current test controller it is called from.

    Am I doing something wrong?

  8. #8
    SitePoint Evangelist
    Join Date
    Jun 2004
    Location
    California
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Did anyone solve this? I'm having this issue now.

  9. #9
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK it seems my earlier response was wrong. The controller that is used is invoked in the setup of the functional test. If you need to test a different controller, write a new test case.

  10. #10
    SitePoint Member
    Join Date
    Oct 2006
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Smile

    After checking out how the process method works, I was able to do the following and be successful:

    Code:
    old_controller = @controller
    @controller = LoginController.new
    post(
      :attempt_login,
      {:user => {:name => 'joe', :password => 'password'}}
    )
    @controller = old_controller
    #process won't let you set the controller, it just gathers it from the @controller instance variable. Well, just redefine that to be the controller that you want to post to, and then set it back to what it had been.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •