Получение "Octokit::Client не реализует #customer" при запуске тестов с Rspec
Я создаю тесты, используя Rspec для Rails API, который использует Octokit для GitHub OAuth, но тесты, связанные с проверкой пользовательских данных, продолжают терпеть неудачу с этой ошибкой:
1) CustomerAuthenticator#perform when code is correct should save the customer when it does not exist
Failure/Error:
allow_any_instance_of(Octokit::Client).to receive(
:customer).and_return(customer_data)
Octokit::Client does not implement #customer
# ./spec/lib/customer_authenticator_spec.rb:51:in `block (4 levels) in <main>'
2) CustomerAuthenticator#perform when code is correct should reuse already registered customer
Failure/Error:
allow_any_instance_of(Octokit::Client).to receive(
:customer).and_return(customer_data)
Octokit::Client does not implement #customer
# ./spec/lib/customer_authenticator_spec.rb:51:in `block (4 levels) in <main>'
3) CustomerAuthenticator#perform when code is correct should create and set customer access token
Failure/Error:
allow_any_instance_of(Octokit::Client).to receive(
:customer).and_return(customer_data)
Octokit::Client does not implement #customer
# ./spec/lib/customer_authenticator_spec.rb:51:in `block (4 levels) in <main>'
Finished in 0.23353 seconds (files took 0.5394 seconds to load)
33 examples, 3 failures
Failed examples:
rspec ./spec/lib/customer_authenticator_spec.rb:55 # CustomerAuthenticator#perform when code is correct should save the customer when it does not exist
rspec ./spec/lib/customer_authenticator_spec.rb:59 # CustomerAuthenticator#perform when code is correct should reuse already registered customer
rspec ./spec/lib/customer_authenticator_spec.rb:65 # CustomerAuthenticator#perform when code is correct should create and set customer access token
Это часть моего customer_authenticator_spec.rb
:
context 'when code is correct' do
let(:customer_data) do
{
login: 'hello',
name: Faker::Name.name,
url: Faker::Internet.unique.url,
avatar_url: Faker::Internet.url,
provider: Faker::App.name,
slug: Faker::Internet.unique.slug,
email: Faker::Internet.unique.email,
location: Faker::Address.country
}
end
# Stub the gem's method to return what we want without sending real requests
before do
# Overrides the method to skip the real method's body and return error
allow_any_instance_of(Octokit::Client).to receive(
:exchange_code_for_token).and_return('validaccesstoken')
# Allow any instance of Octokit to receive Customer method and return customer data
allow_any_instance_of(Octokit::Client).to receive(
:customer).and_return(customer_data)
end
it 'should save the customer when it does not exist' do
expect{ subject }.to change{ Customer.count }.by(1)
end
it 'should reuse already registered customer' do
customer = create :customer, customer_data
expect{ subject }.not_to change{ Customer.count }
expect(authenticator.customer).to eq(customer)
end
it 'should create and set customer access token' do
expect{ subject }.to change{ AccessToken.count }.by(1)
expect(authenticator.access_token).to be_present
end
end
Это мое customer_authenticator.rb
:
class CustomerAuthenticator
class AuthenticationError < StandardError; end
attr_reader :customer, :access_token
def initialize(code)
@code = code
end
def perform
raise AuthenticationError if code.blank?
raise AuthenticationError if token.try(:error).present?
prepare_customer
@access_token = if customer.access_token.present?
customer.access_token
else
customer.create_access_token
end
end
private
def client
# Asign new Octokit objet to the instance variable if it wasn't assigned yet
@client ||= Octokit::Client.new(
client_id: ENV['GITHUB_CLIENT_ID'],
client_secret: ENV['GITHUB_CLIENT_SECRET']
)
end
def token
@token ||= client.exchange_code_for_token(code)
end
def customer_data
# Converts Sawyer::Resource to hash, then queries the desired attributes
@customer_data ||= Octokit::Client.new(access_token: token).customer.to_h.slice(:login, :name, :url, :avatar_url, :email)
end
def prepare_customer
@customer = if Customer.exists?(login: customer_data[:login])
Customer.find_by(login: customer_data[:login])
else
Customer.create(customer_data.merge(provider: 'github'))
end
end
attr_reader :code
end
И мой customer.rb
модель:
class Customer < ApplicationRecord
# Constants
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
# Mandatory attributes
validates :login,
presence: true,
uniqueness: true
validates :name,
presence: true
validates :url,
presence: true,
uniqueness: true
validates :avatar_url,
presence: true
validates :provider,
presence: true
validates :slug,
presence: true,
uniqueness: true
# Optional attributes
validates :email,
presence: false,
uniqueness: true,
length: { minimum: 6 },
format: { with: VALID_EMAIL_REGEX }
# Order newly registered customers first
scope :recent, -> { order(created_at: :desc ) }
# Active Record associations
has_one :access_token, dependent: :destroy
end
Что может быть причиной этой проблемы и каковы возможные результаты? Я использую Octokit 4.10.0, Rails 5.2.0 и Ruby 2.5.1.
Заранее спасибо!