-Мне удалось написать тесты для этих ассоциаций для моделей, теперь застрял на контроллерах.
require 'rails_helper'
RSpec.describe 'Payments', type: :request do
let(:valid_attributes) do
{ first_name: 'mutebi', last_name: 'godfrey', phone_number: '+256780140670', address: 'kampala', money_paid: '6000', date: '25/08/2023',
nin_number: 'KK45896587450P', user_id: '5', home_id: '9' }
end
let(:invalid_attributes) do
skip('Add a hash of attributes invalid for your model')
end
describe 'GET /index' do
it 'renders a successful response' do
Payment.create! valid_attributes
get payments_url, headers: valid_headers, as: :json
expect(response).to be_successful
end
end
describe 'GET /show' do
it 'renders a successful response' do
payment = Payment.create! valid_attributes
get payment_url(payment), as: :json
expect(response).to be_successful
end
end
end
1) Payments GET /index renders a successful response
Failure/Error: Payment.create! valid_attributes
ActiveRecord::RecordInvalid:
Validation failed: User must exist, Home must exist
# ./spec/requests/payments_spec.rb:17:in `block (3 levels) in <main>'
2) Payments GET /show renders a successful response
Failure/Error: payment = Payment.create! valid_attributes
ActiveRecord::RecordInvalid:
Validation failed: User must exist, Home must exist
# ./spec/requests/payments_spec.rb:25:in `block (3 levels) in <main>'
# frozen_string_literal: true
module Api
module V1
class PaymentsController < ApplicationController
before_action :authenticate_user!
before_action :set_payment, only: %i[show edit update destroy]
# GET /payments or /payments.json
def index
if user_signed_in?
@payments = current_user.payments.order(created_at: :desc)
render json: @payments.to_json(include: %i[home user])
else
render json: {}, status: 401
end
end
# GET /payments/1 or /payments/1.json
def show
@payment = current_user.payments.find(params[:id])
render json: @payment.to_json(include: %i[home user])
end
# GET /payments/new
def new
@home = Home.find(params[:home_id])
@payment = @home.payments.new
end
# GET /payments/1/edit
def edit; end
# POST /payments
def create
@home = Home.find(params[:home_id])
@payment = @home.payments.create(payment_params) do |p|
p.user = current_user # if user_signed_in?
end
if @payment.save
render json: @payment.to_json(include: %i[home user])
else
render json: @payment.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /payments/1 or /payments/1.json
def update
@home = Home.find(params[:home_id])
@payment = @home.payments.find(params[:id])
if @payment.update
render json: { notice: 'Payment was successfully updated.' },
status: :ok
else
render json: { error: 'Unable to update payment' },
status: :unprocessable_entity
end
end
# DELETE /payments/1 or /payments/1.json
def destroy
@home = Home.find(params[:home_id])
@payment = @home.payments.find(params[:id])
@payment.destroy
render json: { notice: 'Payment succefully removed' }
end
private
# Use callbacks to share common setup or constraints between actions
def set_payment
@payment = Payment.find(params[:id])
end
# Only allow a list of trusted parameters through.
def payment_params
params.require(:payment).permit(:first_name, :last_name, :phone_number, :address, :money_paid, :date,
:nin_number, :user_id, :home_id)
end
end
end
end
Я хотел бы знать, как я могу использовать заводские рельсы для ботов. Я использовал его со спецификациями модели, что легко, но с запросами мне оказалось сложно реализовать
Ну, что вы на самом деле пробовали/исследовали? В чем проблема, которую вы обозначили? Для этой комбинации нет недостатка в обучающих программах.
я использовал factory_bot_rails с моделями, как показано ниже. FactoryBot.define do factory :payment do first_name { 'Mutebi' } last_name { 'Godfrey' } phone_number { '+256780140670' } address { 'Kampala' } money_paid { '9.99' } nin_number { 'NLJ8589654785P' } home_id { 1 } date { '2023-04-07' } user_id { '7' } статус { 'ожидание' } домашний пользователь end end . я только застрял в том, как я могу использовать эту спецификацию запроса
Вы бы использовали фабрики, например, с let!(:payments) { FactoryBot.create_list(:payments, 3) }. Но вы не должны жестко кодировать эти идентификаторы - НИКОГДА. Вместо этого следуйте инструкциям по ассоциациям github.com/thoughtbot/factory_bot/blob/main/…
Макс дал много полезных советов, но чтобы ответить на ваш вопрос прямо: да, вы можете использовать FactoryBot для всех тестов, моделей, контроллеров и т. д. Ошибка, которую вы получаете, связана с тем, что рельсы ожидают, что будет пользователь с идентификатором 5 и Дома с идентификатором 9, но вы их не создали.
Короткий и милый FactoryBot можно использовать для любого теста, контроллера и модели.





Вы так и не поняли, что такое фабрики и как их использовать. Фабрики должны генерировать уникальные данные, которые вы сможете использовать в своих тестах.
Таким образом, чтобы очистить свою фабрику, вы можете использовать гем ffaker для генерации псевдослучайных данных вместо ваших личных данных (которые вы не должны использовать следующим образом):
FactoryBot.define do
factory :payment do
first_name { FFaker::Name.first_name }
last_name { FFaker::Name.last_name }
phone_number { FFaker::PhoneNumberNL.international_mobile_phone_number }
address { FFaker::Address.street_address }
money_paid { FFaker::Number.decimal }
nin_number { FFaker::Identification.ssn }
user # DO NOT HARDCODE ID's!
home # DO NOT HARDCODE ID's!
end
end
Использование псевдослучайных данных в ваших тестах позволяет избежать того, чтобы ваши тесты зависели от информации, не относящейся к тесту. Это одна из главных причин, почему вы должны использовать фабрики вместо приспособлений.
Затем вы используете фабрику в своих спецификациях на этапе настройки теста:
require 'rails_helper'
RSpec.describe 'Payments', type: :request do
let(:payment) { FactoryBot.create(:payment) }
describe 'GET /index' do
let!(:payments) { FactoryBot.create_list(:payment, 5) }
it 'renders a successful response' do
get payments_url, headers: valid_headers, as: :json
expect(response).to be_successful
end
end
describe 'GET /show' do
it 'renders a successful response' do
get payment_url(payment), as: :json
expect(response).to be_successful
end
it 'has the correct JSON' do
get payment_url(payment), as: :json
expect(response.parsed_body).to match(a_hash_including(
payment.attributes.slice(
"first_name", "last_name", "address" # ...
)
))
end
end
end
Спасибо за твои усилия, брат. ты дал мне шаг, чтобы пойти
Вы пометили вопрос с помощью FactoryBot, но на самом деле вы его не используете. Я думаю, что довольно ясно, где вам нужно провести больше исследований. Кроме того, то, как вы структурируете эти тесты, довольно странное -
Payment.create! valid_attributesне относится к примеру. Настройка зависимостей теста должна выполняться черезlet!илиbefore, чтобы вам не пришлось повторяться.