2017-05-19 44 views
0

とサービスオブジェクトの仕事私は、次の仕事を持っている:テストRSpecの

class Test::MooJob < ApplicationJob 
    queue_as :onboarding 

    def perform 
    avariable = Test::AragornService.build("a").call 
    if avariable.status == true 
     puts "job succeeded" 
    end 
    end 
end 

とサービスは次のようになります。

module Test 
    class AragornService 

    def self.build(x) 
     self.new(x) 
    end 

    def initialize(x) 
     @x = x 
    end 

    def call 
     10.times do 
     Rails.logger.info @x 
     end 

     return ServiceResult.new :status => true, :message => "Service Complete", :data => @x 

    rescue => e 
     Bugsnag.notify(e, :context => 'service') 
     return ServiceResult.new :status => false, :message => "Error occurred - #{e.message}" 
    end 

    end 
end 

私は以下のスペックでそれをテストしようとしています:

# bundle exec rspec spec/jobs/test/moo_job_spec.rb 
require "rails_helper" 

describe Test::MooJob do 
    subject(:job) { described_class.perform_later } 
    subject(:job_now) { described_class.perform_now } 

    let(:key) { "a" } 

    it 'queues the job' do 
    ActiveJob::Base.queue_adapter = :test 
    expect { job }.to have_enqueued_job(described_class) 
     .on_queue("onboarding") 
    end 

    it 'calls the aragorn service once' do 
    allow(Test::AragornService.new(key)).to receive(:call).and_return(ServiceResult.new(:status => true)) 
    expect_any_instance_of(Test::AragornService).to receive(:call).exactly(1).times 
    job_now 
    end 

end 

なぜ可変値がnilを返し続けるのですか 次のエラーが表示される "未定義のメソッドはnilのための `状態:NilClass」

しかし、私は、単純なブール値を返すとき、

は()のテスト:: AragornService.new(キー)を許可受信する。(:を呼び出す).and_return(真)

それは本当

にavariable値を設定し、ここでServiceResultクラスです:

class ServiceResult 
    attr_reader :status, :message, :data, :errors 

    def initialize(status:, message: nil, data: nil, errors: []) 
    @status = status 
    @message = message 
    @data = data 
    @errors = errors 
    end 

    def success? 
    status == true 
    end 

    def failure? 
    !success? 
    end 

    def has_data? 
    data.present? 
    end 

    def has_errors? 
    errors.present? && errors.length > 0 
    end 

    def to_s 
    "#{success? ? 'Success!' : 'Failure!'} - #{message} - #{data}" 
    end 

end 

答えて

1

そのあなただけの無関係なインスタンスにexpectionsを設定しているので、あなたの仕様で:

allow(Test::AragornService.new(key)).to 
    receive(:call).and_return(ServiceResult.new(:status => true)) 

これは、二重を返すようにTest::AragornService.buildをスタブにより、あなたはそれを解決することができますTest::AragornService.build

class Test::MooJob < ApplicationJob 
    queue_as :onboarding 

    def perform 
    avariable = Test::AragornService.build("a").call 
    if avariable.status == true 
     puts "job succeeded" 
    end 
    end 
end 

によって作成されたインスタンスを達成するために何もしない:

double = instance_double("Test::AragornService") 
allow(double).to receive(:call).and_return(ServiceResult.new(status: true)) 

# bundle exec rspec spec/jobs/test/moo_job_spec.rb 
require "rails_helper" 

describe Test::MooJob do 
    let(:perform_later) { described_class.perform_later } 
    let(:perform_now) { described_class.perform_now } 
    let(:service) { instance_double("Test::AragornService") } 

    before do 
    # This injects our double instead when the job calls Test::AragornService.build 
    allow(Test::AragornService).to receive(:build).and_return(service) 
    end 

    it 'queues the job' do 
    # this should be done in `rails_helper.rb` or `config/environments/test.rb` not in the spec! 
    ActiveJob::Base.queue_adapter = :test 
    expect { perform_later }.to have_enqueued_job(described_class) 
     .on_queue("onboarding") 
    end 

    it 'calls the aragorn service once' do 
    expect(service).to receive(:call).and_return(ServiceResult.new(status: true)) 
    perform_now 
    end 
end 
+0

tha返信のためのnks、私はこれらを今試してみましょう。 – EnderWiggins

+0

今このエラーを解消する1)Test :: MooJobがaragornサービスを一度呼び出す 失敗/エラー:(Test :: AragornService)を受け取る(:call) Test :: AragornServiceが実装していない: – EnderWiggins

+0

'Test :: AragornService'クラスの期待値を設定します。あなたが渡すダブルに設定する必要があります。' 'expect(double).to receive(:call)' ' – max