Тестирование Rails с помощью rspec

У меня проблема с тестированием в рельсах с помощью rspec. В общем, у меня есть структура между 4 моделями, но пока я пытаюсь решить свое тестирование для двух из них. Я использую faker и FactoryGirl, и у меня есть следующие фабрики:

 require 'faker'

 FactoryGirl.define do
   factory :user do |f|
     f.name { Faker::Name}
     f.email { Faker::Internet.email}
     f.password {Faker::Internet.password}
     f.role {"Kindergarten"}
   end
 end




 require 'faker'

 FactoryGirl.define do
   factory :child do |f|
     f.name { Faker::Name}
     f.city { Faker::Address.city}
     f.postalcode {Faker::Number.between(30000,35000)}
     f.streed {Faker::Address.street_name}
     f.add_number {Faker::Address.secondary_address}
     f.disability { Faker::Boolean.boolean}
     f.halal { Faker::Boolean.boolean}
     f.koscha {Faker::Boolean.boolean}
     f.vegetarian {Faker::Boolean.boolean}
     f.vegan {Faker::Boolean.boolean}
     f.allday { Faker::Boolean.boolean}
     f.gender { Faker::Number.between(0,1)}
     f.user_id {Faker::Number.between(1,10)}
   end
 end

и мой тест контроллера выглядит так

 require 'rails_helper'
 require 'factory_girl_rails'

 describe UsersController do

   before do
     3.times { FactoryGirl.create(:child)}
   end

   describe "GET #show" do
     let(:user) { FactoryGirl.create(:user) }
     before { get :show, id: user.id}
     it "assigns the requested user to @user" do
       assigns(:user).should eq user
     end
     it "renders  the :show template"
   end

   describe "GET #new" do
     let(:user) { FactoryGirl.create(:user) }
     it "assigns a new User to @user" do
       get :new, id: user.id
       assigns(:user).should be_a_new(User)
     end
     it "renders  the :new template"
   end

 end

Когда я пытаюсь запустить тест, я получаю это сообщение об ошибке

  UsersController GET #new assigns a new User to @user
      Failure/Error: 3.times { FactoryGirl.create(:child)}

      ActiveRecord::RecordInvalid:
        Validation failed: User can't be blank

Мои отношения и проверки в моделях следующие

 class Child < ApplicationRecord

   has_many :relations, :dependent => :destroy
   accepts_nested_attributes_for :relations
   belongs_to :user
   validates :user, presence: true
   validates :name, presence: true, length: { maximum: 50 }
   validates :city, presence: true, :on => :create
     validates :postalcode, presence: true, numericality: true
       validates :streed, presence: true
         validates :add_number, presence: true

 validates :disability, inclusion: { in: [true, false] }
 validates :halal, inclusion: { in: [true, false] }
 validates :koscha, inclusion: { in: [true, false] }
 validates :vegetarian, inclusion: { in: [true, false] }
 validates :vegan, inclusion: { in: [true, false] }
 validates :allday, inclusion: { in: [true, false] }

 validates :gender, presence: true

 end


 class User < ApplicationRecord
   attr_accessor :remember_token, :activation_token, :reset_token
   has_many :children, dependent: :destroy
   has_many :kindergartens, dependent: :destroy
   has_many :relations, dependent: :destroy
   before_save   :downcase_email
   before_create :create_activation_digest
   validates :name, presence: true, length: { maximum: 50 }
   VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
   validates :email, presence: true, length: { maximum: 255 },
                     format: { with: VALID_EMAIL_REGEX },
                     uniqueness: { case_sensitive: false }

 validates :role, presence: true


   has_secure_password
   validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
 end

Моя проблема в том, что я не уверен, есть ли ошибка в моем коде rspec или я допустил ошибку в своих проверках и отношениях в моих обычных моделях. Кто-нибудь может мне помочь?

В дочерней фабрике f.user_id должен ссылаться на существующую запись пользователя. В настоящее время это не так, что вызывает эту пустую ошибку при создании дочернего объекта. Используйте f.assocation(:user, :factory => :user) вместо линии f.user_id. Если ваш набор тестов не требует, чтобы объект Child имел связанную запись User, вы можете смоделировать метод user для Child только для этого контекста теста, сэкономив вам некоторые характеристики

MrYoshiji 14.03.2018 21:02

Кстати, FactoryGirl.create_list(:factory_name, 3) более эффективен, чем 3.times { create(:factory_name) }

MrYoshiji 14.03.2018 21:04

@MrYoshiji, оставь это как ann annswer

max pleaner 14.03.2018 22:20

Спасибо за помощь. Я пробовал, как вы сказали, с заменой строки f.user_id, но у меня появилась новая ошибка с неправильным количеством аргументов Сбой / ошибка: f.assocation (: user,: factory =>: user) {Faker :: Number.between (1,10)} ArgumentError: неправильное количество аргументов (дано 3, ожидается 1..2)

Pyrmon55 14.03.2018 22:57

вы можете просто сказать association :user или даже просто user

mr_sudaca 14.03.2018 23:35

Хорошо, извините за мои глупые вопросы, но я действительно плохо разбираюсь в rspec ... Я переписал свой f.user_id на f.association(:user, :factory => :user) {Faker::Number.between(1,10)}, но мой тест не работает, потому что теперь есть проблемы с кодом в тесте. Я изменил, чтобы изменить деталь id: user.id, но получаю ошибку Failure/Error: before { get :show, id: user.id} ArgumentError: unknown keyword: id

Pyrmon55 15.03.2018 00:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
103
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Думаю, лучше бы вам всю фабрику выложить. И я думаю, вам не нужен require faker, если он у вас есть в Gemfile.

FactoryGirl.define do
  factory :child do 
    name { Faker::Name}
    city { Faker::Address.city}
    postalcode {Faker::Number.between(30000,35000)}
    streed {Faker::Address.street_name}
    add_number {Faker::Address.secondary_address}
    disability { Faker::Boolean.boolean}
    halal { Faker::Boolean.boolean}
    koscha {Faker::Boolean.boolean}
    vegetarian {Faker::Boolean.boolean}
    vegan {Faker::Boolean.boolean}
    allday { Faker::Boolean.boolean}
    gender { Faker::Number.between(0,1)}
    user
  end
end

Внутренние спецификации, когда вам нужно создать дочерний элемент для конкретного пользователя:

let(:current_user) { create :user }
let(:child) { create :child, user: current_user }

Попробуйте изменить спецификацию вашего контроллера:

 describe UsersController do
   let(:user) { create(:user) }

   describe "GET #show" do

     before { get :show, params: { id: user.id } }
     it "assigns the requested user to @user" do
       assigns(:user).should eq user
     end
     it "renders  the :show template"
     it { expect(response).to have_http_status 200 }
   end

   describe "GET #new" do
     before { get :new }

     it "assigns a new User to @user" do
       assigns(:user).should be_a_new(User)
     end
     it "renders  the :new template"
   end
 end

Большое спасибо за вашу помощь! Я заменил эту часть в своем коде, но before { get :show, id: user.id} выдает ошибку. Можно мне показать, как я могу переставить первый тест? Ошибка следующая: NameError: undefined local variable or method user 'для # <RSpec :: ExampleGroups :: UsersController :: GETShow`

Pyrmon55 15.03.2018 10:17

Спасибо за помощь! Я думаю, что в моем коде есть фундаментальная ошибка. Я изменил свой код, как ваш, и теперь получаю сообщение об ошибке, что метод create isn не определен undefined method create

Pyrmon55 15.03.2018 11:09

@ Pyrmon55, замените create на FactoryGirl.create. Почему у вас в тесте линия require 'factory_girl_rails'? Он должен работать автоматически, если у вас есть этот драгоценный камень в Gemfile

Vasilisa 15.03.2018 11:47

Большое спасибо за Вашу помощь!

Pyrmon55 15.03.2018 21:36

Другие вопросы по теме