簡體   English   中英

使用Rails和PostgreSQL獲取Rspec單元測試范圍

[英]Getting Rspec unit test coverage with Rails and PostgreSQL

我正在嘗試為以下模型問題編寫單元測試...

require 'active_support/concern'

module Streamable
  extend ActiveSupport::Concern

  def stream_query_rows(sql_query, options = 'WITH CSV HEADER')
    conn = ActiveRecord::Base.connection.raw_connection
    conn.copy_data("COPY (#{sql_query}) TO STDOUT #{options};") do
      binding.pry
      while row = conn.get_copy_data
        binding.pry
        yield row
      end
    end
  end
end

到目前為止,我已經通過以下規范與之抗爭……

context 'streamable' do
  it 'is present' do
    expect(described_class.respond_to?(:stream_query_rows)).to eq(true)
  end

  context '#stream_query_rows', focus: true do
    let(:sql_query) { 'TESTQRY' }
    let(:sql_query_options) { 'WITH CSV HEADER' }
    let(:raw_connection) do
      Class.new do
        def self.copy_data(args)
          yield
        end

        def self.get_copy_data
          return Proc.new { puts 'TEST' }
        end
      end
    end

    before do
      allow(ActiveRecord::Base).to receive_message_chain(:connection, :raw_connection).and_return(raw_connection)

      described_class.stream_query_rows(sql_query)
    end


    it 'streams data from the db' do
      expect(raw_connection).to receive(:copy_data).with("COPY (#{sql_query}) TO STDOUT #{sql_query_options};")
    end
  end
end

雖然我可以得到第一個期望值,但是,我可以觸發第一個binding.pry,無論我如何嘗試,我似乎都無法超越第二個。

這是錯誤...

LocalJumpError:
       no block given (yield)

我只想對此進行單元測試,理想情況下不打數據庫,僅測試對象的通信。 這也可以並且將在許多模型中用作流數據的選項。

參考文章: https : //shift.infinite.red/fast-csv-report-generation-with-postgres-in-rails-d444d9b915ab

有沒有人對如何完成此存根和/或調整規范有任何指示,以便涵蓋以下內容?

   while row = conn.get_copy_data
        binding.pry
        yield row
      end

回答

在查看了下面的評論和建議之后,我能夠重構該規范,現在覆蓋率達到100%。

  context '#stream_query_rows' do
    let(:sql_query) { 'TESTQRY' }
    let(:sql_query_options) { 'WITH CSV HEADER' }
    let(:raw_connection) { double('RawConnection') }
    let(:stream_query_rows) do
      described_class.stream_query_rows(sql_query) do
        puts sql_query
        break
      end
    end

    before do
      allow(raw_connection).to receive(:copy_data).with("COPY (#{sql_query}) TO STDOUT #{sql_query_options};"){ |&block| block.call }
      allow(raw_connection).to receive(:get_copy_data).and_return(sql_query)
      allow(ActiveRecord::Base).to receive_message_chain(:connection, :raw_connection).and_return(raw_connection)
    end

    it 'streams data from the db' do
      expect(raw_connection).to receive(:copy_data).with("COPY (#{sql_query}) TO STDOUT #{sql_query_options};")
      stream_query_rows
    end

    it 'yields correct data' do
      expect { stream_query_rows }.to output("#{sql_query}\n").to_stdout_from_any_process
    end
  end

就像錯誤說的那樣,您正在yield ,但尚未提供要調用的塊。

如果您的方法需要一個塊,則在調用它時需要提供一個。

為此,您需要更改以下行:

      described_class.stream_query_rows(sql_query)

像這樣:

      described_class.stream_query_rows(sql_query) { puts "this is a block" }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM