Reputation: 11
When I try to write test to a method in controller I received undefined method host error.
Here is the example code blocks below
In rspec file:
require 'rails_helper'
RSpec.describe FooController, type: :controller do
before do
@controller = FooController.new
@controller.params = ActionController::Parameters.new({ foo_id: foo.id, })
@set_foo = @controller.send(:set_foo_data)
end
and in foo controller:
def set_foo_data
@foo_data = {
table_type: :foo,
.
.
data_url: foos_path,
}
end
data_url part causing this issue.
I checked with byebug and data_url was nil.
Upvotes: 1
Views: 354
Reputation: 102423
The reason this doesn't work is that controllers are Rack middleware and expect to be initialized with a request. Its also just not how you should be coding or testing your code in the first place. Bin it.
Controller specs use the get
, post
, etc methods that actually create an instance of the controller with a mocked request.
get :foo
would then call the foo
method directly on the controller instance. You do not initialize controllers directly. If you feel tempted to do this its a very good sign you're doing something very wrong.
Unit testing controllers with controller specs is an extremely flawed approach that's discouraged by both the RSpec and Rails teams - you're mocking out huge parts of the application like the middleware and routes and it lets so many bugs through your tests.
The modern way to test a Rails application is to just test the actions of your controller by sending HTTP requests. This means that you should ONLY test the methods that actually correspond to a route and test your application through the response it provides (the headers and body) and eventually the side effects. In RSpec-Rails this is provided through request, feature and system specs.
Everything else in your controller like this method should be private - and you don't test privates.
Upvotes: 2