I'd like to include the request helpers (from ActionDispatch::Integration::RequestHelpers [ApiDock], like post and xhr methods) also in some specs outside of my controller specs. The problem is that these request helpers are only included in spec/controller and when a controller is described.
What do I have to include/require in those specs?
I am using RSpec 2 and Rails 3.
I just solved the problem by including the below code in my acceptance helper. If you are not Steak then just simply put it in spec helper or require it from somewhere else. post and xhr methods are now available in that spec regardless in what spec it is or in what directory you are.
The code is derived from RSpec::Rails::RequestExampleGroup
RSpec::Core::ExampleGroup.class_eval do
include ActiveSupport::Concern
include ActionDispatch::Integration::Runner
include RSpec::Rails::BrowserSimulators
def app
::Rails.application
end
def last_response
response
end
end
I know it's 4 years later and many things have of course changed, but since I stumbled on this question while searching how to make other tests behave like controller tests (and thus have post and get methods and the like) I wanted to point out this solution that works with RSpec 3: if you add this to the spec_helper
config.include RSpec::Rails::RequestExampleGroup, type: :request, example_group: { file_path: /spec\/(api|integration)/
it will make all tests in the given path have support for controller methods.
Related
I got a helper method:
has_permission?
In a Module called:
module ApplicationHelper
Inside app/helpers.
I also have an IntegrationTest which includes it:
include ApplicationHelper
My Integration test calls one of my controllers via get request.
On call I want to test if my integration test arrives at a certain method.
On this way is has to pass a few of the methods, one of those being the
has_permission?
In order to make sure this method passes I wanted to stub it.
Object.any_instance.expects(:has_permission?).returns(false)
Doesn't work
ApplicationHelper.expects(:has_permission?).returns(false)
Doesn't work either because it's not a static method.
Is there a way I can stub the helpers non-static method within the test so I can make it return false in all cases?
The test:
test "test try to edit without permission" do
#curr = users(:me)
sign_in #curr
SellingController.expects(:validate).never
post enable_update_user_selling_path(id: #user, params: {user: {sell: "1"}})
end
Stumbled across this when trying to work out how to stub an ApplicationHelper method in an ActionDispatch::IntegrationTest in Rails 5; not sure if that's exactly what you're trying to achieve but I ended up doing something like this
MyController.view_context_class.any_instance.expects(:my_method).returns(true)
It looks as though since Rails 5, helper methods aren't simply mixed into the controller classes directly hence the view_context_class bit.
Seems to work, hopefully this will be helpful to someone!
Forgot to post how I ended up solving this:
SellingController.any_instance.stubs(:has_permission?).returns(false)
I a have some code I'd like to refactor out of my step definitions and put them inside.. helpers?
Oh and please also say how to include them, I am really having a hard time finding any solid info on that.
Straight from the rspec documentation here: https://www.relishapp.com/rspec/rspec-core/docs/helper-methods/define-helper-methods-in-a-module#include-a-module-in-all-example-groups
Include a module in all example groups
Given a file named "include_module_spec.rb" with:
require './helpers'
RSpec.configure do |c|
c.include Helpers
end
RSpec.describe "an example group" do
it "has access to the helper methods defined in the module" do
expect(help).to be(:available)
end
end
When
I run rspec include_module_spec.rb
Then
the examples should all pass
You may also benefit from a a support/helpers folder Or equivalent which is covered pretty well here: How to include Rails Helpers on RSpec
I am testing http/https content for images that are on a web application running Rails 2.3. The layout is basic. I have my controllers with accompanying test directories including functional and integration folders with tests.
I'm still relatively new to Rails but I was wondering if there was a way to create a file that can test attachments across different controllers. For example, I need to test if whether the images on this web app are either http or https on the About/Projects/People/Accounts/ and Explore controllers. Instead of opening each of the about_controller_test, project_controller_test, etc. files writing the lines of code, I wanted to know if there was a way that I can make a master file that includes all of the controllers.
What I would like to do is to create some sort of module that I can include/extend the controllers in. This makes sense in my head but I run into the problem with naming conventions. If I wanted to make an attachments_test.rb, I wouldn't be able to do this because I don't have an attachments_controller.rb file that maps to it. How can I work around this?
All I would like is to make a file named along the lines of testing_attachment_protocols_test.rb which doesn't map to any controller but where I can put my tests in. I want to have one file to write my tests for different controllers instead of writing 1 test in several files. Would this file be included into test_helper.rb? Any help would be appreciated. Thanks.
---------EDIT-----------------------
I figured out the structure that I basically would like to implement for the test. Below is the general structure of the test that I would like to do.
require File.dirname(__FILE__) + '/../test_helper'
require 'open-uri'
def controller
......
end
class controller; def rescue_action(e) raise e end: end
class controller < Test::Unit::TestCase
def setup
#controller = controller
#request = ActionController::TestRequest.new
#response = ActionController::TestResponse.new
end
test "attachments url pattern for home page should include http when not logged in" do
setup
get :home
assert not_logged_in
#puts #response.body
assert_select("a img", :url =~ /sw.amazonaws/) do |anchor|
assert_equal 'http', anchor.protocol
end
end
end
Now the thing that I have trouble now is what to put in the method call for controller. My goal is to try to be as dynamic as possible. My goal is pretty much to create an attribute accessor method for different Controllers. Any thoughts?
I'm new to Ruby (RoR) and rspec.
I have the basic project scaffold and a controller within project/app/controllers/books_controller.rb
Then I'm trying to setup rspec in project/spec/controllers/book_spec.rb
There also exists project/spec/spec_helper.rb that book_spec.rb requires. This file is where I'm trying to include the books_controller.rb file.
How do I include the books_controller.rb file so book_spec.rb has the Book object so when I run rspec, it works?
Currently I've tried things like require_relative "../app/controllers/books_controller" and it doesn't work. It gives me an error like:
uninitialized constant ApplicationController ... in 'require_relative'
Any help would be great.
You don't need to manually include your controllers, just follow the rspec naming conventions and describe the desired object and everything will work fine.
Your controller spec should be named books_controller_spec.rb. That is the exact same name as your controller with a _spec added at the end. This is not a hard requirement but a highly suggested convention as a book_spec.rb really implies a Book model spec rather than a controller.
The critical part is that in your spec you describe the desired object, e.g.
describe BooksController do
#...
end
You might also want to have a look at the rspec-rails gem which provides some useful generators for specs. Ideally you integrate with Rails so whenever you generate a new model or controller a new spec is created for you as well.
I've been writing RSpec tests for some Rails controllers and I've discovered a strong impulse to ensure that the Authlogic authentication is working properly. I also feel like I should be verifying that each action uses the same application-wide layout. However, writing tests for this behavior in every single action seems silly.
What I'd like to see are one-line matchers for filters and layouts, similar to Shoulda's matchers for associations and verifications. Unfortunately, no such matchers seem to be available (except for some Test::Unit macros for filters in this blog post). I'm tempted to just write them myself, but not being able to find anyone who's already done it makes me question whether or not a need for such matchers actually exists.
So my question is, how do you test your controllers' common behavior (if you test it at all), and would one-liner matchers testing filters and layouts be useful? Myself, I'm trying to decide between one-liners in the controller specs combined with speccing the filter explicitly, or just speccing the filter and ignoring the filters and layouts in the controllers (since they're only one line of code anyway).
I don't like the idea of writing specs for filters -- that seems too close to the implementation. If you had used TDD/BDD methods to build your controller from scratch, presumably you'd have written the action first, added some logic (e.g. to handle authentication) and then realized it should go into a filter instead. If your spec is along the lines of "Reject an index request if the current user is not the account user", your spec ought to be able to do something like (aircode):
current_user = Factory.create(:unauthorized)
controller.should_not receive(:index)
get :index
request.should redirect_to(some_safe_path)
And it doesn't matter whether the action is using a filter or not.
You can DRY up controller specs with Rspec macros. So (more hand-waving):
describe MyController do
should_reject_anonymous(self)
...
end
module ControllerMacros
def should_reject_anonymous(test_controller)
describe test_controller, "Authentication" do
it "rejects index" do
test_controller.should_not_receive(:index)
get :index
response.should redirect_to(some_safe_path)
end
end
end
end