get & post methods in controller's test

I'm using RSpec (through the gem rspec-rails) for testing and developing my application. Then, I've tried to "test" a controller and run up against a something that in last, I'm not understanding: post and get methods. I've searched them in RoR doc, but their's not documented.

In my route file:   controller :sessions do     post 'login', action: :login_create     get 'login', action: :login     get 'logout', action: :logout   end

At the beginning, I was thinking that post will simulate an http post request at the specified url, while get a http get one, so I've writed:   describe "POST 'login'" do     it "returns http success" do       post 'login'       response.should be_success       response.should render_template 'sessions/login_create'     end   end

But this will load the login action and not the login_create! After a lot of searching and trying, I've wrote:       post :login_create ... And it works as expected. However, after that I've tried:       get :login_create ... And this works also! O_o

So, what this kind of methods really do and how are intended to be used?

How about:

  controller :sessions do     match '/login' => :login_create, :via => :post     match '/login' => :login, :via => :get     match '/logout' => :logout   end

7stud -- wrote in post #1074532:

Your route syntax is confusing to me. How about:

  controller :sessions do     match '/login' => :login_create, :via => :post     match '/login' => :login, :via => :get     match '/logout' => :logout   end

...which is pieced together from here:

ActionDispatch::Routing

Equals effect, but the one I've used is more succinct :slight_smile: It also explained in "HTTP helper methods" paragraph of the linked api.

The problem isn't in the route, but in the strange behavior of get and post, instance methods of ActionController::TestCase::Behavior

The problem isn't in the route, but in the strange behavior of get and post, instance methods of ActionController::TestCase::Behavior

My rspec tests seem to work as you would expect. I used a controller named Dogs to test the routes:

require 'spec_helper'

describe "Dogs Pages" do

  describe "POST to /login" do     it "returns http success" do       post '/login'       response.should be_success       response.should render_template 'dogs/login_create'       response.body.should include('hello world')     end   end

  describe "GET to /login" do     it "should have h1 of 'Doggie'" do       visit '/login'       page.should have_selector('h1', text: "Login")     end   end

end

If I change the 'post' to 'get', that test fails.

That's strange °_° In my app it fails:

But this will load the login action and not the login_create! After a

lot of searching and trying, I’ve wrote:

  post :login_create

… And it works as expected. However, after that I’ve tried:

  get :login_create

… And this works also! O_o

Controller specs bypass your routes entirely (as part as action invocation goes, they’re still used if you try to generate a url inside the action).

If you do

get :action_name

then it will invoke that action with a get request, whether there’s a route for it or not.

post ‘/login’

fails because there are is no ‘/login’ action (but there is a ‘login’ one).

If you write an spec request spec (or a rails integration test) then get/post are the rack test methods instead which do take actual paths.

Fred

Frederick Cheung wrote in post #1074851:

Sorry, my tests were inside an integration('request') test:

/spec/requests/dog_pages_spec.rb

In my rails tutorial book, it says that inside a controller test, you can't use urls at all, e.g

get '/about' get '/'

...you can only do:

get 'actionA' get 'actionB'

Correct, although it would be more than a little perverse not to use the request type you expect.

Fred

Ok, thanks to both of you for clearing my mind :slight_smile: