To implement our second step, we’re going to cheat again and simulate the posting of a message by calling the models directly. This allows us to focus on building the messages page without getting too distracted. Let’s implement the second step definition:
| Given(/^the User has posted the message "([^"]*)"$/) do |message_text| |
| expect(User.count).to eq 1 |
| FactoryGirl.create(:message, :content => message_text, :user => User.first) |
| end |
A Given means that something has happened in the past. If a Given describes stuff that should be in the database, it is usually preferable to create those records directly using the database (ActiveRecord)—without going through the UI. This gives us the freedom to implement certain functionality without depending on other UI screens to be developed first. It also runs faster and makes our step definitions simpler.
Notice that we’ve made an assertion that there should be only one user in the system. We know that in the feature we’re writing right now there’s only one user, but it’s possible that this step definition could be reused in the future by another scenario involving more than one and behave in surprising ways. Since the step definition talks about the user, it’s implying that there’s only one user in the system. So, we use the assertion to make sure that’s true. Now when we run the features, of course poor old FactoryGirl complains that it doesn’t know what a message should look like:
| 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" |
| Factory not registered: message (ArgumentError) |
| ./features/step_definitions/user_steps.rb:8 |
| features/see_messages.feature:4 |
| When I visit the page for the User |
| Undefined step: "I visit the page for the User" (Cucumber::Undefined) |
| features/see_messages.feature:5 |
| Then I should see "this is my message" |
| Undefined step: "I should see "this is my message"" (Cucumber::Undefined) |
| features/see_messages.feature:6 |
| |
| Failing Scenarios: |
| cucumber features/see_messages.feature:2 |
| |
| 1 scenario (1 failed) |
| 4 steps (1 failed, 2 undefined, 1 passed) |
| 0m0.108s |
| |
| You can implement step definitions for undefined steps with these snippets: |
| |
| When(/^I visit the page for the User$/) do |
| pending # Write code here that turns the phrase above into concrete actions |
| end |
| |
| Then(/^I should see "([^"]*)"$/) do |arg1| |
| pending # Write code here that turns the phrase above into concrete actions |
| end |
Let’s fix that, again by creating a very simple factory definition in features/support/factories.rb:
| factory :message do |f| |
| f.association :user |
| f.content 'Test message content' |
| end |
Again, when we run Cucumber, we’re told we need to create a Message model:
| 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" |
| uninitialized constant Message (NameError) |
| ./features/step_definitions/user_steps.rb:8 |
| features/see_messages.feature:4 |
| When I visit the page for the User |
| Undefined step: "I visit the page for the User" (Cucumber::Undefined) |
| features/see_messages.feature:5 |
| Then I should see "this is my message" |
| Undefined step: "I should see "this is my message"" (Cucumber::Undefined) |
| features/see_messages.feature:6 |
| |
| Failing Scenarios: |
| cucumber features/see_messages.feature:2 |
| |
| 1 scenario (1 failed) |
| 4 steps (1 failed, 2 undefined, 1 passed) |
| 0m0.113s |
| |
| You can implement step definitions for undefined steps with these snippets: |
| |
| When(/^I visit the page for the User$/) do |
| pending # Write code here that turns the phrase above into concrete actions |
| end |
| |
| Then(/^I should see "([^"]*)"$/) do |arg1| |
| pending # Write code here that turns the phrase above into concrete actions |
| end |
We’ll fix that once more by generating our very basic Message model and then running the database migrations:
| $ bin/rails g model Message user_id:integer content:string |
| $ bin/rake db:migrate db:test:prepare |
That got us past the previous error, but now we have uncovered another missing piece:
| 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" |
| undefined method ‘user=’ for #<Message:0x63756b65> |
| Did you mean? user_id= (NoMethodError) |
| ./features/step_definitions/user_steps.rb:8 |
| features/see_messages.feature:4 |
| When I visit the page for the User |
| Undefined step: "I visit the page for the User" (Cucumber::Undefined) |
| features/see_messages.feature:5 |
| Then I should see "this is my message" |
| Undefined step: "I should see "this is my message"" (Cucumber::Undefined) |
| features/see_messages.feature:6 |
| |
| Failing Scenarios: |
| cucumber features/see_messages.feature:2 |
| |
| 1 scenario (1 failed) |
| 4 steps (1 failed, 2 undefined, 1 passed) |
| 0m0.128s |
| |
| You can implement step definitions for undefined steps with these snippets: |
| |
| When(/^I visit the page for the User$/) do |
| pending # Write code here that turns the phrase above into concrete actions |
| end |
| |
| Then(/^I should see "([^"]*)"$/) do |arg1| |
| pending # Write code here that turns the phrase above into concrete actions |
| end |
Each new error means we’ve made a little bit of progress, but we want to get to passing! Our step is now failing where we’ve asked FactoryGirl to create the message and given her a user to associate with the message. She hasn’t been able to do that because we haven’t told Rails yet that the two objects have a relationship.
18.223.237.29