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:

http://api.rubyonrails.org/classes/ActionDispatch/Routing.html

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: