Получение "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.

Заранее спасибо!

0 ответов

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