【问题标题】:Rspec: Failure/Error: expect(qbase).to have_received(:with_user_id).with(1)Rspec:失败/错误:expect(qbase).to have_received(:with_user_id).with(1)
【发布时间】:2019-09-24 21:30:48
【问题描述】:

如何检测 CarQuery 的实例是否调用了具有特定参数的方法? (我认为这是我的问题,但如果我错了请告诉我)。

有没有更好的测试方法?

错误

Search#base_filters should call with_limit method on query_object when user_id is passed in
     Failure/Error: expect(qbase).to have_received(:with_user_id).with(1)

       (Double "CarQuery").with_user_id(1)
           expected: 1 time with arguments: (1)
           received: 0 times

搜索查询

class Search
  def self.call(current_user, params)
    new(current_user, params).call
  end

  def initialize(current_user, params)
    @params = params
    @current_user = current_user
  end

  def call
    base_filters(CarQuery.new(@current_user)).relation
  end

  private

  def base_filters(query_object)
    query_object.with_user_id(@params[:user_id]) if @params[:user_id].present?
    query_object
  end
end

Rspec 测试

RSpec.describe Search, type: :model do
  describe "#base_filters" do
    it "should call with_limit method on query_object when user_id is passed in" do

      current_user = create(:user)
      qbase =spy('CarQuery')
      expect(qbase).to have_received(:with_user_id).with(1)
      Search.call(current_user, {user_id: 1})
    end
  end
end

【问题讨论】:

    标签: ruby rspec rspec-rails ruby-on-rails-5.2


    【解决方案1】:

    必须调用 spy 上的方法才能工作

    如果你使用的是spy,那么你需要调用它上面的方法,然后测试该方法是否被接收到。请参阅有关间谍 here 的 rspec 文档。或者,您也可以使用双倍。它们都很相似,但你不能指望替身能像间谍一样工作。

    RSpec.describe Search, type: :model do
      describe "#base_filters" do
        it "should call with_limit method on query_object when user_id is passed in" do
          current_user = create(:user)
          qbase =spy('CarQuery')
          qbase.with_user_id(1) # <-------- you need to add this line here first
          ## but does qbase even have a method called 'with_user_id'? if not,
          ## it will still fail
          expect(qbase).to have_received(:with_user_id).with(1) 
          # If you don't add the line above, of course it will fail, 
          ## you haven't sent qbase any messages! It won't work otherwise.
          ## I'm not sure what the line below is doing in relation to your tests?
          Search.call(current_user, {user_id: 1})
        end
      end
    end
    

    【讨论】:

    • Search.call 调用 CarQuery.new().with_user_id,请看代码
    • @user2012677 是的,Search.call 调用 CarQuery,但您的测试永远不会通过:您需要正确设置间谍,并正确设置预期。
    • 如果你知道怎么做,请帮忙
    • @user2012677 问题是您不了解应该如何设置测试和间谍 - 请准备好我在上面发布的链接。为了做到这一点,我会重组课程。你不能直接测试它,因为你没有公开暴露它。
    • 我在发布之前阅读了您发布的页面并再次阅读。我仍然不知道解决方案,因此我发布了。我没有直接测试它。.call正在调用base_filters,它调用了方法。
    【解决方案2】:

    通过依赖注入解决

    如果有更好的解决方案,请发表。

    搜索查询

    class Search
      def self.call(current_user, params, query_object_override = nil)
        new(current_user, params, query_object_override).call
      end
    
      def initialize(current_user, params, query_object_override = nil)
        @params = params
        @current_user = current_user
        @query_object = query_object_override
      end
    
      def call
        base_filters(query_object).relation
      end
    
      private
    
      def query_object
        @query_object ||= CarQuery.new(@current_user)
      end
    
      def base_filters(query_object)
        query_object.with_user_id(@params[:user_id]) if @params[:user_id].present?
        query_object
      end
    end
    

    Rspec 测试

    RSpec.describe Search, type: :model do
      describe "#base_filters" do
        it "should call with_user_id method on query_object when user_id is passed in" do
    
          current_user = create(:user)
          query_object = spy('CarQuery')
          Search.call(current_user, {user_id: 1}, query_object)
          expect(query_object).to have_received(:with_user_id )
        end
      end
    end
    

    【讨论】:

    • 太棒了!这是完全正确的 - 您必须公开它才能以您想要的方式对其进行测试。
    猜你喜欢
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 2013-06-16
    • 1970-01-01
    相关资源
    最近更新 更多