Reputation: 2319
I am building a Rails 4 engine that provides some controllers and models that will then be used by several of our apps. I am in the process or writing the unit tests, and I am having problems with the actions in the controllers that make a redirect_to
.
In the controller that I am testing, I have the following actions:
def index
end
def new
@block = GlobalIpBlock.new
end
def create
@block = GlobalIpBlock.new(create_params)
if @block.save
flash[:success] = "The IP has been successfully blocked."
redirect_to action: 'index'
else
render 'new'
end
end
and in the controller test I have these two tests:
test "should get new block" do
get :new, use_route: :watchdog
assert_response :ok
assert_not_nil assigns(:block)
end
test "should create global ip block" do
assert_difference('GlobalIpBlock.count') do
post :create, block: {some_param: 'some value'}, use_route: :watchdog
end
assert_redirected_to :index
end
The first test passes but the second throws an error:
ActionController::UrlGenerationError: No route matches {:action=>"index"}
I have no routes created in the engine and in the routes of the dummy test app it only mounts the engine. The reason for that is that I want the hosting apps to provide their own routes to the controllers/actions of the engine.
Still, this doesn't seems to be the issue here since the test for the action new
passes. Furthermore, I have tried creating the routes in the engine by doing:
resources :global_ip_blocks, except: [:edit, :update]
but that didn't help, neither did doing that in the routes of the dummy test app.
I am guessing the redirect_to
is not finding the route in the same way that removing use_route: :watchdog
from the get/post in the tests fail but how can I fix that? Is there something like a global way of telling unit tests to use_route: :watchdog
?
Upvotes: 1
Views: 890
Reputation: 65467
You should be able to fix this using:
class MyControllerTest < ActionController::TestCase
def setup
@routes = MyEngine::Engine.routes
end
end
Also, look out for the deprecation notice in the logs due to the use of use_route
which is like:
DEPRECATION WARNING: Passing the
use_route
option in functional tests are deprecated. Support for this option in theprocess
method (and the relatedget
,head
,post
,patch
,put
anddelete
helpers) will be removed in the next version without replacement. Functional tests are essentially unit tests for controllers and they should not require knowledge to how the application's routes are configured. Instead, you should explicitly pass the appropiate params to theprocess
method. Previously the engines guide also contained an incorrect example that recommended using this option to test an engine's controllers within the dummy application. That recommendation was incorrect and has since been corrected. Instead, you should override the@routes
variable in the test case withFoo::Engine.routes
. See the updated engines guide for details.
Upvotes: 2