简体   繁体   English

RSpec如何在注入方法中进行测试

[英]Rspec how to test in inject method

I have a method that looks like this: 我有一个看起来像这样的方法:

  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

This method returns a hash with the IDs as keys and the results of the division as the values. 此方法返回一个散列,其ID为键,而除法的结果为值。

I have successfully tested top_level_comment_count and code_review_assigned count, but I am having trouble figuring out how I can test the 4 other things that are in the do block: 我已经成功测试了top_level_comment_count和code_review_assigned计数,但是在弄清楚如何测试do块中的其他4件事时遇到了麻烦:

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

I am trying to test .first and this is what I have so far: 我正在尝试测试.first,这是我到目前为止的结果:

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

I cannot get the last it statement to pass. 我无法传递最后的it语句。 I am trying to expect(item).to receive(:first), but it says this in the error: 我试图期望(item).receive(:first),但是它在错误中这样说:

Failure/Error: expect(item).to receive(:first) (Double).first(*(any args)) expected: 1 time with any arguments received: 0 times with any arguments 失败/错误:Expect(item).to receive(:first)(Double).first(*(any args))预期:1次接收到任何参数:0次使用任何参数

Any idea why this is not passing? 知道为什么没有通过吗? The other two its are passing 其他两个正在过去

The item double is never used in the test, so when it reaches: item的双从未在测试中使用,所以当它到达:

expect(item).to receive(:first)

it fails. 它失败。

If you were expecting the item double to be used within the inject block here: 如果您希望将double item用于此处的inject块中:

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

merely by virtue of it having the same name, it doesn't work that way. 仅仅因为它具有相同的名称,它就不能那样工作。 You'd need to define a method on the avg_top_level_comments double that returns the item double when inject is called. 您需要在avg_top_level_comments double上定义一个方法,该方法在调用inject时返回double item

But, you shouldn't do that. 但是,您不应该这样做。 Throw all of this out and use real model instances for the test. 扔掉所有这些,并使用真实的模型实例进行测试。 It will be much easier to read and maintain. 它将易于阅读和维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM