Еще одна проблема из руководства Rails 3 в главе 11.1

#ruby-on-rails

#ruby-on-rails

Вопрос:

Я не могу пройти 3 теста. Вот ошибки:

 Failures:
1) Users micropost associations should have a micropost attribute
 Failure/Error: @mp1 = Factory(:micropost, :user => @user, :created_at => 1.day.ago)
 Validation failed: User can't be blank
 # ./spec/requests/users_spec.rb:69:in `block (3 levels) in <top (required)>'

2) Users micropost associations should have the right microposts in the right order
 Failure/Error: @mp1 = Factory(:micropost, :user => @user, :created_at => 1.day.ago)
 Validation failed: User can't be blank
 # ./spec/requests/users_spec.rb:69:in `block (3 levels) in <top (required)>'

3) Users micropost associations should destroy associated microposts
 Failure/Error: @mp1 = Factory(:micropost, :user => @user, :created_at => 1.day.ago)
 Validation failed: User can't be blank
 # ./spec/requests/users_spec.rb:69:in `block (3 levels) in <top (required)>'
  

Любые мысли о том, где искать, были бы высоко оценены. Я опубликую любые примеры кода, которые вам понадобятся, чтобы помочь мне разобраться.

Большое вам спасибо!

Согласно запросу, вот user_spec.rb

 require 'spec_helper'

describe "Users" do
describe "signup" do    
describe "failure" do

  it "should not make a new user" do
    lambda do
      visit signup_path
      fill_in "Name",         :with => ""
      fill_in "Email",        :with => ""
      fill_in "Password",     :with => ""
      fill_in "Confirmation", :with => ""
      click_button
      response.should render_template('users/new')
      response.should have_selector("div#error_explanation")
    end.should_not change(User, :count)
  end
end

describe "success" do
  it "should make a new user" do
    lambda do
      visit signup_path
      fill_in "Name",           :with => "Example User"
      fill_in "Email",          :with => "user@example.com"
      fill_in "Password",       :with => "foobar"
      fill_in "Confirmation",    :with => "foobar"
      click_button
      response.should have_selector("div.flash.success", :content => "Welcome")
      response.should render_template('users/show')
    end.should change(User, :count).by(1)
  end
end
end

describe "sign in/out" do

describe "failure" do

  it "should not sign the user in" do
    visit signin_path
    fill_in :email, :with => ""
    fill_in :password, :with => ""
    click_button
    response.should have_selector("div.flash.error", :content => "Invalid")
  end
end

describe "success" do

  it "should sign a user in and out" do
    user = Factory(:user)
    visit signin_path
    fill_in :email, :with => user.email
    fill_in :password, :with => user.password
    click_button
    controller.should be_signed_in
    click_link "Sign out"
    controller.should_not be_signed_in
  end
end
end

describe "micropost associations" do

before(:each) do
  @user = User.create(@attr)
  @mp1 = Factory(:micropost, :user => @user, :created_at => 1.day.ago)
  @mp2 = Factory(:micropost, :user => @user, :created_at => 1.hour.ago)
end

it "should have a micropost attribute" do
  @user.should respond_to(:microposts)
end

it "should have the right microposts in the right order" do
  @user.microposts.should == [@mp2, @mp1]
end

it "should destroy associated microposts" do
  @user.destroy
  [@mp1, @mp2].each do |micropost|
    Micropost.find_by_id(micropost.id).should be_nil
  end
end
end
end
  

И factories.rb:

 Factory.define :user do |user|
user.name                     "JD Skinner"
user.email                    "jd.skinner@me.com"
user.password                 "password"
user.password_confirmation    "password"
end

Factory.sequence :email do |n|
"person-#{n}@example.com"
end

Factory.define :micropost do |micropost|
micropost.content "foo bar"
micropost.association :user
end
  

Большое вам спасибо!!

-Kagi

Комментарии:

1. Как @user создается или извлекается? И вы создали что-то вроде factories.rb файла и настроили детали для пользователя в этом файле?

2. Пожалуйста, опубликуйте содержимое вашего файла users_spec.rb и вашего файла factories.rb.

Ответ №1:

Должны ли ваши пользователи быть уникальными? Если да…

 Factory.define :user do |user|
  user.sequence(:name) { |n| "Test-#{n}" }
  user.sequence(:email) { |n| "test-user-#{n}@example.com" }
  user.password "password"
  user.password_confirmation "password"
end
  

Комментарии:

1. Имя пользователя не так уж и важно, но адреса электронной почты беспокоят, отсюда и последовательность в блоке sequence в середине factory. Я новичок в Rails (очевидно), и я предполагаю, что ваш способ — это просто другой, более простой способ сделать то же самое?

2. То, как вы определили электронную почту, в настоящее время пытается использовать один и тот же адрес электронной почты для каждой модели. Это может быть частью вашей проблемы. Вы должны использовать адрес электронной почты, как показано выше — возможно, вы можете определить блок в другом месте (как вы уже сделали), но ваше определение пользователя должно явно вызывать метод sequence, а не использовать буквальный адрес электронной почты.

Ответ №2:

Я думаю, Validation failed: User can't be blank это произошло из-за того, что вы не определили (или определили с неправильными значениями) @attr переменную, в user_spec.rb

 @user = User.create(@attr)
  

Попробуйте это вместо

 before(:each) do
  @user = Factory(:user)
  @mp1 = Factory(:micropost, :user => @user, :created_at => 1.day.ago)
  @mp2 = Factory(:micropost, :user => @user, :created_at => 1.hour.ago)
end