【问题标题】:RSpec any_instance return selfRSpec any_instance 返回自我
【发布时间】:2012-12-15 15:44:09
【问题描述】:

我正在尝试对某个类的任何实例进行存根。我需要存根fetch 方法,它用一些数据填充自我。

如何访问self 变量,修改它并返回fetch 方法?

MyObject.any_instance.stub(:fetch) { self }

不返回 MyObject 实例。

也许,在这种情况下,模拟更有用。不幸的是,我还没有理解它们。

【问题讨论】:

    标签: ruby rspec


    【解决方案1】:

    有一个open rspec-mocks issue 来解决这个问题。我希望在某个时候解决这个问题,但是以一种不会破坏现有规范套件的方式添加它并不简单,这些规范套件使用 any_instance 和块实现,因为我们会开始产生一个额外的参数(例如对象实例)。

    总体而言,any_instance 在某些情况下可以派上用场,但它有点异味,如果您能找到模拟或存根单个实例的方法,您通常会遇到更少的问题。

    这是我尚未测试但应该可以解决的解决方法:

    orig_new = MyObject.method(:new)
    MyObject.stub(:new) do |*args, &block|
      orig_new.call(*args, &block).tap do |instance|
        instance.stub(:fetch) { instance }
      end
    end
    

    本质上,我们在这里通过挂钩MyObject.new 来模拟any_instance,以便我们可以在每个实例化的新实例上存根fetch

    总而言之,“倾听您的测试”很重要,并且,当某些东西难以测试时,请考虑一下您的设计所代表的内容,而不是立即使用像 any_instance 这样的强大工具。您最初的问题没有为我提供足够的背景信息来推测您的设计,但这绝对是我在需要这样做时开始的地方。

    【讨论】:

      【解决方案2】:

      据我所知,出于某种原因,这似乎是不可能的。我检查了当前的rspec-mocks实现,实际调用存根实现的方法似乎如下:

      # lib/rspec/mocks/message_expectation.rb:450
      def call_implementation(*args, &block)
          @implementation.arity == 0 ? @implementation.call(&block) : @implementation.call(*args, &block)
      end
      

      看起来,块只是由自身调用,而不是通过instance_eval。也许还有另一种技术可以实现您想要的,毕竟我无论如何都不是 RSpec 专家。

      【讨论】:

        猜你喜欢
        • 2014-08-27
        • 2017-08-25
        • 1970-01-01
        • 2012-04-05
        • 2012-12-31
        • 2013-02-28
        • 1970-01-01
        • 2013-08-08
        • 2014-06-26
        相关资源
        最近更新 更多