1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
# Controller specs
Controller specs are marked by `type: :controller` or if you have set
`config.infer_spec_type_from_file_location!` by placing them in `spec/controllers`.
A controller spec is an RSpec wrapper for a Rails functional test
([ActionController::TestCase::Behavior](https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/test_case.rb)).
It allows you to simulate a single http request in each example, and then
specify expected outcomes such as:
* rendered templates
* redirects
* instance variables assigned in the controller to be shared with the view
* cookies sent back with the response
To specify outcomes, you can use:
- standard rspec matchers (`expect(response.status).to eq(200)`)
- standard test/unit assertions (`assert_equal 200, response.status`)
- rails assertions (`assert_response 200`)
- rails-specific matchers:
- [`render_template`](./matchers/render-template-matcher)
```ruby
expect(response).to render_template(:new) # wraps assert_template
```
- [`redirect_to`](./matchers/redirect-to-matcher)
```ruby
expect(response).to redirect_to(location) # wraps assert_redirected_to
```
- [`have_http_status`](./matchers/have-http-status-matcher)
```ruby
expect(response).to have_http_status(:created)
```
- [`be_a_new`](./matchers/new-record-matcher)
```ruby
expect(assigns(:widget)).to be_a_new(Widget)
```
## Examples
```ruby
RSpec.describe TeamsController do
describe "GET index" do
it "assigns @teams" do
team = Team.create
get :index
expect(assigns(:teams)).to eq([team])
end
it "renders the index template" do
get :index
expect(response).to render_template("index")
end
end
end
```
## Views
* by default, views are not rendered. See
[views are stubbed by default](./controller-specs/isolation-from-views) and
[render_views](./controller-specs/render-views) for details.
## Headers
We encourage you to use [request specs](./request-specs/request-spec) if you want to set headers in your call. If you still want to use controller specs with custom http headers you can use `request.headers`:
```ruby
require "rails_helper"
RSpec.describe TeamsController, type: :controller do
describe "GET index" do
it "returns a 200" do
request.headers["Authorization"] = "foo"
get :show
expect(response).to have_http_status(:ok)
end
end
end
```
|