Go gentle on me: I've got the flu and only a few of my neural synapses are firing!
Here's a simple requests test for RSpec:
require 'spec_helper'
describe 'Home Page' do
it 'should mention Home' do
get '/'
response.body.should have_content("Home")
end
end
Great. It works. Now I want to verify that there's an image loaded when visting the home page as well. I assume there's a matcher for images similar to have_content(), so I first go looking for the definition of have_content().
Not found in
https://www.relishapp.com/rspec/search?query=have_content
http://guides.rubyonrails.org/testing.html
http://api.rubyonrails.org/
But the I remember that RSpec has nifty naming rules for matchers, so (e.g.) even?() => be_even(). But even then, searching for "content" in the above doesn't find anything.
(As an aside, I'm pretty sure I'm not looking for the Capybara method of the same name, since I'm doing a get and not visit. Right?)
At the risk of getting this question rejected for being too vague: where the heck is this method coming from, and where do I learn what else I can pass to response.body.should?
RSpec request specs use Capybara, so you can use either get or visit.
If you want to just check that the page has an <img> element with the correct link, you could use:
response.should have_selector('img', :src => '...')
Related
I am writing tests for a Sinatra app that takes input from an API via a gem. Once I have the API response I need to test that the template has correctly rendered. The response of the API will be the HTML of the page that I am loading.
My first instinct was to write a test that looks like this:
describe 'the root path'
it 'should render the index view' do
get '/'
expect(last_response).to render_template(:index)
end
end
Unfortunately when I try this I get the following error: undefined method `render_template'
I was wondering if anyone has encountered this problem - it seems like it should be an easy fix, but I can't seem to find any documentation to help with it.
I'm currently not testing views at all because of time constraints, but I did have some limited successs with Rack::Test.
In theory you can say:
require 'rack/test'
include Rack::Test::Methods
def app
Sinatra::Application
end
describe 'it should render the index view' do
get '/'
expect(last_response).to be_ok
expect(last_response.body).to eq(a_bunch_of_html_somehow)
end
If I were to go this road again, since my views are haml, I could implement the a_bunch_of_html_somehow method using a call to Haml::Engine -- but I'm not sure whether that helps you.
I'm lifting this wholesale from the Sinatra site here -- the page is well worth a read.
We ended up scrapping this approach since it was better handled by integration testing tool suites such as Selenium or Capybara. There is no equivalent that I could find in the basic Sinatra Rspec suite that could do this - it made more sense to move it into a different scope
This is an incredibly newbish question, but I can't seem to find the answer.
I'm building an app that utilizes external APIs heavily, and I'm fairly new to Rails, so it's still a little rough to get around. I can't, for the life of me, figure out how to accept user input and execute a function in my app without writing to a model.
For example, I just want to let a user type in a Twitter username and have it display on the page. I know how to make a form to cache the search in a model, but I can't figure out how to just... make a function happen on a page. I've been breaking my brains on this for several days now.
Please help? :/
You don't need a model to use Rails, but if you don't need ActiveRecord at all, you might benefit from a lighter framework like Sinatra. That doesn't answer your question, but it's worth thinking about if you really have no database requirement for your application.
It sounds like you're just trying to access non-resourceful user input, which is accessible in the controller via the params hash. So, assuming you have set up a valid route for the form action, you use your controller to extract GET or POST parameters.
For example:
# You define a non-resourceful route in routes.rb for your form action.
get 'twitternames/show'
# Form action directs user to GET the following route after filling in the form.
http://example.com/twitternames/show?user=foo
# The controller action extracts the data.
def show
#user = params[:user]
# render the view unless you tell rails to do something else
end
# show.html.erb
<%= #user %>
Creating the right route is the key. Once you've defined a route that can break a URL into the proper segments, the rest will fall into place.
I took a long break from programming, because other things caught my interest. When I picked it back up, I decided it would be a good idea to go back through railstutorial.org, since I found it useful the first time through, but couldn't remember much as I had hoped.
After simply running the command 'rails generate controller Pages home contact' I have a 'spec/controllers/pages_controllers_rspec.rb' file that looks like this:
require 'spec_helper'
describe PagesController do
describe "GET 'home'" do
it "should be successful" do
get 'home'
response.should be_success
end
end
describe "GET 'contact'" do
it "should be successful" do
get 'contact'
response.should be_success
end
end
end
Even though all the routes and controllers are in place as described in chapter 3, Rspec indicates failure. What am I doing wrong?
Both tests fail with messages:
Failure/Error: Unable to find matching line from backtrace
PGError: fe_sendauth: no password supplied
The test database hadn't been created. Don't ask me why. Once I'd gone back in and manually created the test database, tests started passing.
Capybara is confusing me. If I use Capybara in combination with Ruby on Rails 3 and RSpec 2, then in RSpec request tests, the following matcher works:
response.body.should have_selector "div.some_class"
The response object has the class ActionDispatch::TestResponse. But the following line, which should work officially, does not work:
page.should have_selector "div.some_class"
The page object has the class Capybara::Session. In which cases do you have to use the response.body object and when do you have to use a page object ?
So I just ran into similar, and this is I think what's going on:
It depends on code you didn't include here of how you visit the page. I'm writing an rspec request spec.
If I retrieve the page with rspec's own:
get '/some/path'
then response.body.should have_selector works as you say, but page.should does not.
To make Capybara 'page' work (and to make Capybara interactions like click_button or fill_in work), instead of retrieving with rspec's 'get', you need to retrieve with Capybara's 'visit':
visit '/some/path'
page.should have_selector("works")
'page', a capybara method, only gets set when using 'visit', a capybara method.
This does get confusing, all the mixing and matching of different libraries involved in rails testing.
You would use response when you want to use the standard rails methods. And, alternately, you'd use page when you want to use the capybara methods. In capybara you'd most likely use have_css in the example given.
I'm trying to write some tests for emails generated with a mailer class using rspec and email_spec (Ruby on Rails 3.0.7)
I would like to check if the layout used for rendering the email is the layout that was specified in the mailer class.
Any idea on how to do this? I've spent 3 hours searching for a solution but couldn't find anything.
Thanks!
(I realize this is a pretty late response. You've probably found a solution already)
I won't be able to update this answer much, but does this page help? It describes how to check if a layout was rendered. You could make a get request with parameters (example here) then check if the result renders the layout you want it to render.
This is cheating a little bit, since you're not really checking which template got generated...
However, I just wanted to perform a quick sanity check that the right email is (probably) being generated - so this was good enough for my needs:
# In RSpec:
expect(ActionMailer::Base.deliveries.last.subject)
.to eq I18n.t("name.of.email.subject")
# In MiniTest:
assert_equal I18n.t("name.of.email.subject"),
ActionMailer::Base.deliveries.last.subject