Topic: Unit test controller with fake CGI params

Hiya,

Im trying to unit test an app against a browser that works inside a game.  The browser itself works with html 1.0 standard at the moment so its faily simple, however in its header it sends a few variable that relate to the game, like the username.  in PHP it would be something like

echo $_SERVER['GAME_USERNAME']

Now what I have inmy controller is this

u = User.new(
            :name => cgi.params['GAME_USERNAME'],
            :last_seen => Time.now.gmtime
        }

Question 1 is do I need the cgi. bit or can I jusat call params?

So in my test for this controller I need to fake that CGI param, how would I go about doing that, would it be like this

(IGB stands for In Game Browser)

def test_user_from_igb
   get :info, :game_username => 'Fred'
end

Im coding this a bit blind as the spec for the IGB has been written but not the actual IGB itself so I cant test it in the realworld for a bit.  So kinda want to fake it just for my own sanity so I can get this thing coded!

Thanks
- Chris

Re: Unit test controller with fake CGI params

Quick update, I *think* Im doing it right now, got rid of the CGI call and passing params direct as stated in the above, I suppose I shall have to wait until they code the browser to truley find out.

Any comments welcome though smile

Last edited by Catharsis (2006-09-15 09:54:51)

Re: Unit test controller with fake CGI params

The equivalent of $_SERVER in Rails is the env object, not params. So for example $_SERVER['REQUEST_URI'] would be env['REQUEST_URI'] in Ruby/Rails.

The params hash is the equivalent of $_REQUEST in PHP (so $_GET and $_POST together), afaik it doesn't include the server/header data.

Re: Unit test controller with fake CGI params

ah cool, thanks for the post smile

So to set them I do

def test_user_from_igb
    env['GAME_USERNAME'] = 'Fred'
    get :info
end

Re: Unit test controller with fake CGI params

Aha, after a lil search, it appears that the env stuff for the browser is held within the request object, so...

request.env['HTTP_ACCEPT_LANGUAGE']

hopefully I can set them in a similar fashion

Re: Unit test controller with fake CGI params

Well I can log request (the whole object) and even just the env part, how I set them continues to elude me smile

Re: Unit test controller with fake CGI params

Do you need to set them just for testing? Or do you need to set them in your application as well?

I suspect I'ld look at introducing a mock object that wraps env so you can poke/push into it more easily in your tests.

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: Unit test controller with fake CGI params

Just for testing really, in the application they will be set by the browser, but since that isnt coded yet I have to fake it.

Basically I want to theoretically test the website works in the browser without having to load the game and the browser.

Re: Unit test controller with fake CGI params

aha, think I might be onto something, and Im quoting thew api docs here...

get(path, parameters=nil, headers=nil)

Performs a GET request with the given parameters. The parameters may be nil, a Hash, or a string that is appropriately encoded (application/x-www-form-urlencoded or multipart/form-data). The headers should be a hash. The keys will automatically be upcased, with the prefix

Re: Unit test controller with fake CGI params

*sigh* okay chucking it through like that chucks the var through as part of the session... still looking

*grumbles about out of date docs*

Re: Unit test controller with fake CGI params

If anyone is interedsted I now know how to do this.  Didn't find it docced anywhere just stumbled across it.  Been away from this bit of code for a LONG time and all of a sudden it fits into place.  Nice eh...

So my test looks like this..

require File.dirname(__FILE__) + '/../test_helper'
require 'user_controller'

# Re-raise errors caught by the controller.
class UserController; def rescue_action(e) raise e end; end

class UserControllerTest < Test::Unit::TestCase
  def setup
    @controller = UserController.new
    @request    = ActionController::TestRequest.new
    @request.env['FAKE_VAR'] = 'Munky'
    @response   = ActionController::TestResponse.new
  end

  # Replace this with your real tests.
  def test_truth
    assert true
  end

  def test_create_from_igb
    get :create, {}, { :password => 'wibble' }
    assert_response :success
  end

end


Which you can access in rails like this

logger.debug( request.env['FAKE_VAR'] )

Dunno why I didnt think of this sooner, makes so much sense now