【问题标题】:Rspec: Failure of spy to detect method call (my pattern is wrong)Rspec:间谍检测方法调用失败(我的模式错误)
【发布时间】:2019-09-25 15:47:46
【问题描述】:

如何测试一个方法是否在另一个方法中被调用?

我需要测试 ListingQuery.call() 调用 base_filter 方法

代码

module ListingsQuery
  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
      @type = params[:market] || params[:type] || "all"
      @current_user = current_user
      @type = if @type.present?
                @type.downcase.singularize
              else
                "listing"
              end
      @query_object = query_object_override
    end

    def call
      relation_for(query_object)
    end

    private

    def relation_for(query_object_instance)
      if query_object_instance.class == ListingsQuery::Car
        car_filters(query_object_instance).relation
      else
        raise ArgumentError, "ListingsQuery 'Class: #{query_object_instance.class}' does not exist"
      end
    end

    def car_filters(query_object)
      base_filters(query_object)
      other_filters(query_object)
      query_object
    end

    def query_object
      @query_object ||= query_object_for(@type, @current_user) # => ListingQuery::Car
    end
  end
end

### 测试

  current_user = spy("User")
  query_object_class = ListingsQuery::Car
  query_object = spy(query_object_class.name)

  allow_any_instance_of(RSpec::Mocks::Double).to receive(:class) { query_object_class }
  allow_any_instance_of(ListingsQuery::Search).to receive(:base_filters) { query_object }
  so = ListingsQuery::Search.call(current_user, {}, query_object)
  expect(so).to have_received(:base_filters)

错误

 1) ListingsQuery::Search#car_filters should call base_filters
     Failure/Error: expect(so).to have_received(:base_filters)

       (Double "ListingsQuery::Car").base_filters(*(any args))
           expected: 1 time with any arguments
           received: 0 times with any arguments

更新也失败了:

  current_user = spy("User")

  query_object_class  = ListingsQuery::Car
  search_object_class = ListingsQuery::Search

  query_object = spy(query_object_class.name)
  allow_any_instance_of(RSpec::Mocks::Double).to receive(:class) { query_object_class }

  allow_any_instance_of(search_object_class).to receive(:base_filters) { query_object }
  expect(search_object_class).to have_received(:base_filters)
  search_object_class.call(current_user, {}, query_object)

错误:

Failure/Error: expect(search_object_class).to have_received(:base_filters)
       #<ListingsQuery::Search (class)> expected to have received base_filters, but that object is not a spy or method has not been stubbed.

【问题讨论】:

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


    【解决方案1】:

    我认为您将变量so 分配给ListingsQuery::Search.call(current_user, {}, query_object) 的结果。这可能有效:

    so = ListingsQuery::Search
    so.call(current_user, {}, query_object)
    expect(so).to have_received(:base_filters)
    

    或者我通常写它们的方式:

    so = ListingsQuery::Search
    expect(so).to receive(:base_filters)
    so.call(current_user, {}, query_object)
    

    【讨论】:

    • 我试过了,但得到了 .. #<:search> 预计会收到 base_filters,但该对象不是间谍或方法没有被存根。
    【解决方案2】:

    这行得通:

    it "should call base_filters" do      
      current_user = spy("User")
      query_object_class  = ListingsQuery::Car
      search_object_class = ListingsQuery::Search
      query_object = spy(query_object_class.name)
      allow_any_instance_of(RSpec::Mocks::Double).to receive(:class) { query_object_class }
      so = search_object_class.new(current_user, {}, query_object)
      allow(so).to receive(:base_filters) { query_object }      
      so.call
      expect(so).to have_received(:base_filters)
    end
    

    由于某种原因allow_any_instance_of 不起作用,我不得不存根特定实例。如果有人知道,我很想知道为什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多