Let’s make the last few changes to make our scenario pass. The next thing we need to do is to implement the last missing step. Add the following to features/step_definitions/view_steps.rb:
| Then(/^I should see "([^"]*)"$/) do |text| |
| expect(page).to have_content(text) |
| end |
We’re using Capybara’s page object and have_content RSpec matcher here to verify that a snippet of text is on the page. We’ll explain more about that in the next chapter. This makes our step go from undefined to failing since the view doesn’t show what we want it to show. Remember—we just hard-coded a message in it.
We’ll work outside-in, starting with the app/views/users/show.html.erb view. Let’s assume the controller will assign an @user variable:
| <% @user.messages.each do |message| %> |
| <p><%= message.content %></p> |
| <% end %> |
If you want, run Cucumber again. That will tell us that, no, there isn’t a @user variable. Let’s fix our controller so that it loads the @user:
| class UsersController < ApplicationController |
| def show |
| @user = User.find(params[:id]) |
| end |
| end |
This isn’t enough to make the scenario pass quite yet. Now we get a new error because we haven’t added the other side to the one-to-many relationship between User and Message. Adding that is simple, since we already created our Message class with a user_id field:
| class User < ActiveRecord::Base |
| has_many :messages |
| end |
And finally—our feature is passing:
| Feature: See Messages |
| |
| Scenario: See another user's messages |
| Given there is a User |
| And the User has posted the message "this is my message" |
| When I visit the page for the User |
| Then I should see "this is my message" |
| |
| 1 scenario (1 passed) |
| 4 steps (4 passed) |
| 0m0.428s |
Excellent. We haven’t actually seen the code in action in a browser yet, but we’ve done all the hard work. And what’s more, we know that whatever we do to the application in the future, this scenario will always guarantee that this core functionality is working. It’s time to call the boss over for a demo.