1

在 rspec 3.1.0 中,规范可以使用 #allow 存根方法:

describe do
  specify do
    o = Object.new
    allow(o).to receive(:foo)
    o.foo
  end
end

这工作正常。但是,如果存根位于类的方法中,则不定义 #allow 方法:

describe do

  class Baz
    def allow_bar(o)
      allow(o).to receive(:bar)
    end
  end

  specify do
    o = Object.new
    Baz.new.allow_bar(o)
    o.bar
  end

end

错误是:

 Failure/Error: allow(o).to receive(:bar)
 NoMethodError:
   undefined method `allow' for #<Baz:0x8de6720>
 # ./bar_spec.rb:5:in `allow_bar'
 # ./bar_spec.rb:11:in `block (2 levels) in <top (required)>'

为什么我在课堂上存根

该测试将其测试替身定义为常规类,而不是使用 rspec 的“double”方法。这是因为测试替身有一个线程。测试替身里面是这段代码:

if command == :close
  # Note: Uses the old (rspec 2) syntax.  Needs to be converted
  # to rspec 3 syntax using the #allow method.
  socket.stub(:getpeername).and_raise(RuntimeError, "Socket closed")
end

这可以防止被测代码在会话关闭后错误地使用套接字。

私人解决方案

我可以通过在 rspec-mock 中调用私有 API 来为测试提供对 #allow 的双重访问权限:

  class Baz
    RSpec::Mocks::Syntax.enable_expect self    # Uses private API
    def allow_bar(o)
      allow(o).to receive(:bar)
    end
  end

这行得通。但是,它在 rspec/mocks/syntax.rb 中被明确标记为私有 API:

  # @api private
  # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
  def self.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
  ...

问题

在 Rspec 3.1 中,我是否可以使用公共API 来使期望语法在类中可用?

4

1 回答 1

0

您可以通过将一些 RSpec 模块/类混合到您的类中来完成此操作:

class MyClass
  include RSpec::Mocks::ExampleMethods::ExpectHost
  include RSpec::Matchers 

  def some_test
    expect(1).to eql(1)
  end
end
于 2015-04-29T18:23:48.617 回答