I am working on the RoR Tutorial chapter 5 exercises and I can't seem to figure out what text to use in place of the "FILL_IN" I've tried reading the error messages by trying to match the actual with the expected. What am I doing wrong? Also, can someone explain how the <expected> and <actual> work in this test since I don't see the words "expected" or "actual" anywhere.
require 'test_helper'
class ApplicationHelperTest < ActionView::TestCase
test "full title helper" do
assert_equal full_title, "Kim's Cool Rails Site"
assert_equal full_title("Help"), "Kim's Cool Rails Site | Help"
end
end
can someone explain how the <expected> and <actual> work
Often a term between angle brackets, like <expected> and <actual> indicates a value that needs to be replaced. In this case, it mentions:
assert_equal <expected>, <actual>
which gives a description of the parameters taken by the assert_equal method. We're meant to replace them with our real-life values. For example,
result = 1 + 1
assert_equal 2, result
Here we've replaced <expected> with 2, and <actual> with result, to test that 1 + 1 = 2, as we expect it to.
I can't seem to figure out what text to use in place of the "FILL_IN"
So the relevant lines in your code are:
assert_equal full_title, FILL_IN
assert_equal full_title('help'), FILL_IN
In both lines, you should replace FILL_IN with whatever the result of the previous parameter is - in this case, full_title, and full_title('help')
So, if full_title gives "Kim's Cool Rails Site", then the first line should be:
assert_equal full_title, "Kim's Cool Rails Site"
And if full_title('Help') gives "Kim's Cool Rails Site | Help", then the second line should be:
assert_equal full_title('Help'), "Kim's Cool Rails Site | Help"
** UPDATES **
So the error you're getting basically says: We expected to see "Ruby on Rails Tutorial Sample App" and instead we say "Kim's Cool Rails Site".
In the example I gave, I just used "Kim's Cool Rails Site" as an example because I didn't know the actual title of your site. You needed to replace "Kim's Cool Rails Site" with whatever the actual title of your site is (ie, whatever full_path returns). So, judging from the error message, the exact code you need for the first line will be:
assert_equal full_title, "Ruby on Rails Tutorial Sample App"
You'll need to figure out the exact text you need for the second line yourself, but you'll basically just have to replace "Kim's Cool Rails Site | Help" with whatever you expect full_title('Help') to return.
I believe this is what you were after....
require 'test_helper'
class ApplicationHelperTest < ActionView::TestCase
test "full title helper" do
assert_equal full_title, "Ruby on Rails Tutorial Sample App"
assert_equal full_title("Help"), "Help | Ruby on Rails Tutorial Sample App"
end
end
Related
I have been working through the Hartl sample app course, and while I have had issues here and there, I have always been able to find answers, or identify the kink in my code by comparing with the tutorial git. However this time I am at a loss and am hoping someone in the community can figure out where I may have gone wrong.
I am getting the following minitest error:
Minitest::Assertion: Expected at least 1 element matching "a[href="/users/14035331"]", found 0..
Expected 0 to be >= 1.
test/integration/users_index_test.rb:15:in `block (2 levels) in <class:UsersIndexTest>'
test/integration/users_index_test.rb:14:in `block in <class:UsersIndexTest>'
Here is the code for the test which is exactly as it appears in the tutorial:
require 'test_helper'
class UsersIndexTest < ActionDispatch::IntegrationTest
def setup
#user = users(:james)
end
test "index including pagination" do
log_in_as(#user)
get users_path
assert_template 'users/index'
assert_select 'div.pagination'
User.paginate(page: 1).each do |user|
assert_select 'a[href=?]', user_path(user), text: user.name
end
end
end
User 14035331 is the ID of the first record in the test.db. Possible issues I can think of but haven't been successful in identifying - User is not on Page 1 (this shouldn't be since it is the first ID record); the test is looking for the NAME field but getting the ID field.
I did find a similar question on here, but it doesn't address this problem. You can see the thread here: Got failure in integration testing of rails
That user is a bit further along, and I really hate to refractor and push forward when my test suite isn't passing.
Thanks to HASHROCKET I was able to determine that somehow my DB was sorted by ID DESC and my test expected it to be ASC. I am not sure how that happened exactly but I added the following line to the end of users.yml to force order by ID ASC and the test is green.
<% User.order(id: :asc) %>
In the exercise, a test is written for the full_title helper and one has to fill in code. Here is the test
require 'test_helper'
class ApplicationHelperTest < ActionView::TestCase
test "full title helper" do
assert_equal full_title, FILL_IN
assert_equal full_title("Help"), FILL_IN
end
end
How does the assert_equal method work here? I'm confused as to what I should put in for the expected and actual.
expected is the value represents the proper behavior, and actual is the what actually gets returned. If full_title is the thing that you're testing, then it should be the actual parameter and the output that you what the method to have should be the expected parameter.
You want to test with the assertion using this format:
assert_equal( expected, actual, [msg] )
So you want to test that the expected value "full_title" in this case will equal the actual value. The last part [msg] is an optional message parameter you can include to clarify your feedback if your test fails. The FILL_IN part is where you insert your actual value. So if full_title has a value of "Welcome To My Site", you would test that value by writing an assertion like:
assert_equal full_title, "Welcome To My Site"
and if the value of full_title("Help") should be "Welcome To My Site | Help"
then you would test it like so:
assert_equal full_title, "Welcome To My Site | Help"
and if you can include the optional message parameter, to make your failure message a bit clearer:
assert_equal full_title, "Welcome To My Site | Help", "This was not the correct title"
and in the event that you're test fails, that message will show up as part of your logs.
There is a Rails guide which goes into more details on how to use assertions: http://guides.rubyonrails.org/testing.html
I am also going through the tutorial and noticed a slight difference from MisterCal's answer in how to write the test.
assert_equal( expected, actual, [msg] )
is the right format but his example uses the full_title method call as the expected when that is the actual result that you are getting.
Below the string is the expected and the helper method call is the actual value you get when calling it. Don't forget to call the method with an argument otherwise you will trigger the default parameter you set earlier
assert_equal "Welcome To My Site | Help", full_title("Help"), "This was not the correct title"
I just completed the Chapter 5 exercises from "The Ruby on Rails tutorial" by Michael Hartl (which is really great) But exercise 4 from section 5.6, I just don't understand how it works.
I have created integration tests using rspec located in spec/requests/static_pages_spec.rb:
shared_examples_for "all static pages" do
it { should have_selector('h1', text: heading) }
it { should have_title(full_title(page_title)) }
end
The full_title function is located in a support directory under spec/support/utilities.rb:
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
Which works great. In exercise 4 in 5.6 we are tasked to remove it by adding a helpers directory and application_helper_spec.rb file spec/helpers/application_helper_spec.rb:
require 'spec_helper'
describe ApplicationHelper do
describe "full_title" do
it "should include the page title" do
expect(full_title("foo")).to match(/foo/)
end
it "should include the base title" do
expect(full_title("foo")).to match(/^Ruby on Rails Tutorial Sample App/)
end
it "should not include a bar for the home page" do
expect(full_title("")).not_to match(/\|/)
end
end
end
and edit utilities.rb to contain just one line spec/support/utilities.rb:
include ApplicationHelper
and all of my tests pass!
My question is how..? How, after removing the full_title util function and only adding the application_helper_spec to test full_title do my original spec tests pass?
If you read the question carefully, he's suggesting that there's redundancy in the code that you can refactor further:
"Eliminate the need for the full_title test helper in Listing 5.29 by
writing tests for the original helper method, as shown in Listing
5.41."
If we look at listing 5.29, he follows with:
"Of course, this is essentially a duplicate of the helper in Listing
4.2, but having two independent methods allows us to catch any typos in the base title. This is dubious design, though, and a better
(slightly more advanced) approach, which tests the original full_title
helper directly, appears in the exercises (Section 5.6)."
So, actually, you have already defined this function in your app/helpers/application_helper.rb file. A simple include statement in your spec/support/utilities.rb file will load all of your functions from app/helpers/application_helper.rb and that is why your tests still pass.
Have fun with the rest of the tutorial!
I'm reading railstutorial chapter 5.6.4.
According to the page the following two code serve same tests.
But I can't understand why it works without having the argument page_title.
Is there special meaning for "foo" string in Rspec?
spec/support/utilities.rb
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
spec/helpers/application_helper_spec.rb
require 'spec_helper'
describe ApplicationHelper do
describe "full_title" do
it "should include the page title" do
expect(full_title("foo")).to match(/foo/)
end
it "should include the base title" do
expect(full_title("foo")).to match(/^Ruby on Rails Tutorial Sample App/)
end
it "should not include a bar for the home page" do
expect(full_title("")).not_to match(/\|/)
end
end
end
spec/support/utilities.rb
include ApplicationHelper
No, the string "foo" does not have any special meaning to RSpec, it is just being used as an example in the test to check if the full_title helper is working correctly.
To answer the other part of your question, if no page title is passed in, then the if statement will take the first path because the page_title variable is empty and you will be returned the base title only. Here is what each of the tests are actually doing:
# This is expected to return "Ruby on Rails Tutorial Sample App | foo", which
# will match /foo/.
it "should include the page title" do
expect(full_title("foo")).to match(/foo/)
end
# This returns the same as above ("Ruby on Rails Tutorial Sample App | foo"),
# but this test is checking for the base title part instead of the "foo" part.
it "should include the base title" do
expect(full_title("foo")).to match(/^Ruby on Rails Tutorial Sample App/)
end
# This returns just "Ruby on Rails Tutorial Sample App" because the page title
# is empty. This checks that the title doesn't contain a "|" character but that
# it only returns the base title.
it "should not include a bar for the home page" do
expect(full_title("")).not_to match(/\|/)
end
This is a "rspec to English" translation of the tests that might help you:
If I give the full_title method the string "foo", the result should:
contain "foo"
contain the base title which is "Ruby on Rails Tutorial Sample App"
not be "|"
The idea behind tests is to make sure your code works using some meaningful examples of the behaviour of the code. You can't test for every possible scenario so you choose one (or more) that describes the functionality of your method the best.
In this case it's passing a string argument "foo" which is often used as a placeholder in programming.
I am working through the Learn Rails By Example book and came across an interesting problem. I'll apologize in advance if I am just doing something wrong. Here is the problem.
In section 3.5, the exercise it asks you to do the following:
You may have noticed some repetition in the Pages controller spec (Listing 3.20). In particular, the base title, “Ruby on Rails Tutorial
Sample App”, is the same for every title test. Using the RSpec
before(:each) facility, which executes a block of code before each
test case, fill in Listing 3.33 to define a #base_title instance
variable that eliminates this duplication. (This code uses two new
elements: a symbol, :each, and the string concatenation operator +.
We’ll learn more about both in Chapter 4, and we’ll see before(:each)
again in Section 6.2.1.) Note that, with the base title captured in an
instance variable, we are now able to align :content with the first
character inside each left parenthesis (. This is my preferred
convention for formatting code broken into multiple lines.
Here is how my pages_controller_spec.rb looks:
describe PagesController do
render_views
before(:each) do
# Define #base_title here.
base_title = "Ruby on Rails Tutorial Sample App"
end
describe "GET 'home'" do
it "should be successful" do
get 'home'
response.should be_success
end
it "should have the right title" do
get 'home'
response.should have_selector("title",
:content => #base_title + " | Home")
end
end
When I load the rails server and open the webpage, everything works perfect. The title shows up as it should per the base_title. However, when I run rspec, I receive the following errors. I'd really like to get this cleared up in rspec. What do you think is wrong?
1) PagesController GET 'home' should have the right title
Failure/Error: :content => #base_title + " | Home")
NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+
# ./spec/controllers/pages_controller_spec.rb:20
Failed examples:
rspec ./spec/controllers/pages_controller_spec.rb:17 # PagesController GET 'home' should have the right title
I think you need #base_title = "Ruby on Rails Tutorial Sample App" at line 6, not base_title. A variable defined as you do there does not automatically become an instance variable