-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
anonymous controllers in integration specs #1596
Comments
@muichkine were you previously (in the 3.0 series) able to use anonymous controllers in request specs? If so this is a regression. Otherwise we'll consider it as a feature request. |
I don't think anonymous controllers were ever supposed to work in feature specs, and given that Rails is pushing towards no controller tests I don't think it makes sense to add anonymous controllers elsewhere, integration tests aren't supposed to be decoupled from implementation. |
@JonRowe we're not talking about |
My bad I meant |
@muichkine can you expand on your use case? |
I agree with the raised points. It makes full sense that
I think we all agree that this is perfectly clear. Now, how should one approach integration test with overriding one/several controllers, for instance to remove the authentication method ? Im my case, it's actually the other way around. I want to test the auth for my API endpoints as if a client. That means not testing controllerl but also the full stack before and after it. So in my understanding: integration tests. :) Here is the best way I came up with so far:
But I hate to have test routes / controllers spilling outside my |
@muichkine the case that you've outlined (bypassing actual code, but testing authentication code) can be achieved with other RSpec tools. I can't think of a good reason for why you'd need an anonymous controller in a request spec. |
@samphippen sorry then I don't know how to bypass actual code without using anonymous controllers or adding code to my app (not in the test code). Any link? |
@muichkine you'll want to start with https://www.relishapp.com/rspec/rspec-mocks/docs. If you're still not sure what to do, I'd suggest asking in our IRC channel or mailing list, but I don't think the solution to your problem is to add anonymous controllers to request specs. |
Thank you @samphippen for the link. I've already hundreds of tests using rspec-mocks (it rocks :)) but I still fail to see how this would help me test requests on controllers only existing in test environment. More explicitly:
How to generate a controller in test against which I can include and test my 3 auth methods individually with requests. I'll think about it some more. :) |
@muichkine there is no replacement for controller tests that does what you want, I suggest you keep using controller tests, thats why the gem exists after all |
Something like this might work: describe Middleware::CatchJsonParseErrors, type: :request do
class TestController < ::ApplicationController
def test
end
end
before do
Rails.application.routes.draw do
post "/test", :to => "test#test"
end
end
it "responds with a status code of 400 when invalid JSON is sent" do
headers = {
"ACCEPT" => "application/json",
"CONTENT_TYPE" => "application/json",
}
body = '{'
post "/test", params: body, headers: headers
expect(response.status).to eq 400
end
end |
thanks @mikehale , and if you also want your existing routes to persist (in case your app somehow depends on them even when testing this controller), you'll need to do this Rails.application.routes.disable_clear_and_finalize = true # preserve original routes
Rails.application.routes.draw do
get "/test", to: "test#test"
end so that your routes are appended rather than fully replaced. |
defining a class in that way will cause the class to become global across specs. If you need to define a custom class in your specs, then it's best to use the block format with before do
klass = Class.new(ApplicationController) do
...
end
stub_const('TestController', klass)
end |
Rack middleware is invoked in request specs, but not in controller specs. Sometimes it is desirable to not couple a rack-middleware-testing request spec to a controller+route defined in This technique can be useful to test rack middleware with a simple, test-only controller and route, all inside a request spec. Here's an example that borrows from the snippets above: # spec/requests/host_header_attack_defense_spec.rb
describe 'Host header attack defense', type: :request do
before do
# Define and stub TestRedirectsController so it does not leak outside this example
klass = Class.new(ApplicationController) do
def index
redirect_to '/foo'
end
end
stub_const('TestRedirectsController', klass)
Rails.application.routes.disable_clear_and_finalize = true # preserve original routes
Rails.application.routes.draw do
get '/test_redirect', to: 'test_redirects#index'
end
end
# Reset routes so they don't include test mapping from above.
after { Rails.application.reload_routes! }
# Mitigated by StripXForwardedHost rack middleware
it 'prevents malicious X-Forwarded-Host redirect' do
host! 'example.tld'
get '/test_redirect', headers: { 'X-Forwarded-Host' => 'attacker.tld' }
expect(response).to redirect_to 'https://example.tld/foo'
end
end |
Hello,
I need to use anonymous controllers in a
:request
spec to test different API auth methods. As ofrspec-rails 3.4.2
,:request
specs do not have access to thecontroller
method as controller specs do. I think it makes sense to allow anonymouse controller in integration tests by default, even more considering that Rails 5 is leaning towards integrations tests vs controller tests.What do you think?
The text was updated successfully, but these errors were encountered: