Rspec如何在注入方法中测试

时间:2015-11-19 21:33:30

标签: ruby-on-rails rspec

我有一个看起来像这样的方法:

  def self.average_top_level_comments_leaders
    top_level_comment_count = CrucibleComment.group(:user_id).where(parent_comment_id: nil).order('count_all DESC').count
    code_review_assigned_count = Reviewer.group(:user_id).order('count_all DESC').count

    division_result = top_level_comment_count.inject({}) do |result, item|
      id = item.first #id =12
      count = item.last #value = 57
      if (count && code_review_assigned_count[id]) 
        result[id] = (count/ code_review_assigned_count[id]).round(2) 
        #result[12] = 57/12 = 3.3, => {12, 3.3}
      end
      result 
    end
  end

此方法返回一个散列,其中ID为键,分区结果为值。

我已成功测试了top_level_comment_count和code_review_assigned计数,但我无法弄清楚如何测试do块中的其他4个内容:

.first, .last, .round(2), result

我正在尝试测试。首先,这是我到目前为止所做的:

describe '#average_top_level_comments_leaders' do
    subject { User.average_top_level_comments_leaders}

    let(:avg_top_level_comments) { double }
    let(:code_review_count) { double }
    let(:item) { double( {id: 12}) }

    context 'when getting the comment count succeeds ' do
      before do
        allow(CrucibleComment).to receive(:group).with(:user_id).and_return(avg_top_level_comments)
        allow(avg_top_level_comments).to receive(:where).with(parent_comment_id: nil).and_return(avg_top_level_comments)
        allow(avg_top_level_comments).to receive(:order).with('count_all DESC').and_return(avg_top_level_comments)
        allow(avg_top_level_comments).to receive(:count).and_return(avg_top_level_comments)

        allow(avg_top_level_comments).to receive(:inject).and_return(avg_top_level_comments)
        allow(item).to receive(:first).and_return(item)

        allow(Reviewer).to receive(:group).with(:user_id).and_return(code_review_count)
        allow(code_review_count).to receive(:order).with('count_all DESC').and_return(code_review_count)
        allow(code_review_count).to receive(:count).and_return(code_review_count)
        allow(code_review_count).to receive(:round).with(2).and_return(code_review_count)
      end

      it 'and the correct parameters are called' do
        expect(CrucibleComment).to receive(:group).with(:user_id)
        subject
      end

      it 'and comment count is calling descending correctly' do
        expect(avg_top_level_comments).to receive(:order).with('count_all DESC')
        subject
      end

      it 'item gets the first result' do
        expect(item).to receive(:first)
        subject
      end
    end
  end

我无法通过最后一个声明。我试图期望(项目)。接收(:第一),但它在错误中说明了这一点:

失败/错误:期待(项目)。收到(:第一)        (双).first(*(any args))            预期:任何参数1次            收到:0次带有任何参数

知道为什么这不通过?其他两个正在传递

1 个答案:

答案 0 :(得分:2)

item double从未在测试中使用过,所以当它到达时:

expect(item).to receive(:first)

失败了。

如果您希望在此item块中使用inject双精度数字:

division_result = top_level_comment_count.inject({}) do |result, item|

仅凭它具有相同的名称,它不会那样工作。您需要在avg_top_level_comments双精度上定义一个方法,该方法在调用item时返回inject双精度。

但是,你不应该这样做。抛出所有这些并使用真实的模型实例进行测试。它将更容易阅读和维护。