使用Rspec模拟Ruby on Rails中的单例类



我尝试为下面的类创建一个mock:

module EstablishmentsQueryService
class << self
def find_by_id(id)
Establishment.find_by!(id:)
rescue ActiveRecord::RecordNotFound
raise EstablishmentNotFoundError.new id
end
end
end

尝试测试我的控制器

# frozen_string_literal: true
module Api
module V1
# Controllewr to manager Establishments
class EstablishmentsController < Api::V1::ApiController
before_action :validate_id, only: %i[destroy update show]
before_action :load_establishment, only: %i[destroy update show]
def show; end
def create
@establishment = Establishment.new(establishment_params)
@establishment = EstablishmentService.save(@establishment)
render status: :created
end
def destroy
EstablishmentService.delete(@establishment)
end
def update
@establishment.attributes = establishment_params
@establishment = EstablishmentService.save(@establishment)
end
private
def validate_id
message = I18n.t('establishment_controller.id.invalid', id: params[:id])
UuidValidateService.call(params[:id], message)
end
def load_establishment
@establishment = EstablishmentsQueryService.find_by_id(params[:id])
end
def establishment_params
params.require(:establishment).permit(:name, :cnpj, :description)
end
end
end
end

跟随我的测试:

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Api::V1::Establishments', type: :request do
describe 'GET /api/v1/establishments/:id' do
context 'when has establishment' do
let(:establishment) { build(:establishment, id: p, created_at: DateTime.now, updated_at: DateTime.now) }
before do
allow_any_instance_of(EstablishmentsQueryService).to receive(:find_by_id).and_return(establishment)
get "/api/v1/establishments/#{establishment.id}"
end
it 'then http status is ok' do
expect_status_is_ok
end
it 'has body equal to expected' do
except_field_by_field(establishment, body_to_open_struct, %i[id name cnpj description])
end
end
context 'when has no establishment' do
before do
get "/api/v1/establishments/#{UUID.new.generate}"
end
it 'then http status is not_found' do
expect_status_is_not_found
end
end
context 'when use invalid id' do
before { get "/api/v1/establishments/#{FFaker::Lorem.word}" }
it 'then http status is bad_request' do
expect_status_is_bad_request
end
end
end
describe 'PUT /api/v1/establishments/:id' do
let(:establishments_query_service) { allow(EstablishmentsQueryService) }
let(:establishments_service) { allow(EstablishmentsService) }
context 'when updated with success' do
let(:establishment) { build(:establishment) }
let(:id) { UUID.new.generate }
before do
establishments_query_service.to receive(:find_by_id) { |p| build(:establishment, id: p, created_at: DateTime.now, updated_at: DateTime.now) }
establishments_service.to receive(:save) do |p|
to_return = p
to_return.created_at = DateTime.now
to_return.updated_at = DateTime.now
end
put "/api/v1/establishments/#{id}"
end
it 'then http status is ok' do
expect_status_is_ok
end
it 'has body equal to expected' do
actual = body_to_open_struct
except_field_by_field(establishment, actual, %i[name cnpj description])
expected(actual.id).to eq(id)
end
end
context 'when has no establishment' do

end
context 'when has constraint violation' do

end
end
describe 'DELETE /api/v1/establishments/:id' do
end
describe 'POST /api/v1/establishments' do
end
end

如果我使用allow_any_instance_of测试忽略配置,使用实际配置并失败,因为没有数据存储。如果我使用double,我收到一个跟随错误:

Api:: V1::机构得到/Api/V1/机构/:id当已建立http状态就可以了失败/错误:allow_any_instance_of (EstablishmentsQueryService)。接收(find_by_id) .and_return(建立)

我认为正确的是user allow_any_instance_of因为这个配置是用于静态方法的,但没有工作

我如何模拟我的类来测试我的控制器?我使用Ruby 3.1.2, rails 7.0.3和respect -rails 5.1.2谢谢你

我发现了我的问题,我忘记在我的confi中使用with()定义预期参数

允许(EstablishmentsQueryService)。接收(find_by_id); (establishment.id).and_return(建立)

相关内容

  • 没有找到相关文章

最新更新