如何规范私有方法

Mik*_*ike 54 rspec ruby-on-rails

我有一个私有方法的模型,我想用RSpec来规范,
你通常怎么做?你只测试调用私有的方法吗?
还是私人的?如果是的话,你怎么办?

Ari*_*jan 118

我总是采用这种方法:我想测试我的类暴露的公共API.

如果您有私有方法,则只能从公开给其他类的公共方法中调用它们.因此,如果您测试那些公共方法在所有条件下都按预期工作,您还证明了它们使用的私有方法也可以工作.

我承认我遇到过一些特别复杂的私人方法.在那种极端情况下,你想测试它们,你可以这样做:

@obj.send(:private_method)
Run Code Online (Sandbox Code Playgroud)

  • 这是另一个有趣的方法http://kailuowang.blogspot.com/2010/08/testing-private-methods-in-rspec.html (3认同)
  • 如果方法需要一些参数,那么args呢?我将尝试使用`@obj.send(:private_method,arg1,arg2)` (3认同)
  • 我意识到这个答案很老,但我不认为证明公共方法的工作意味着他们称之为私有方法的工作.在两个地方的错误逻辑碰巧相互抵消的情况下,是否会出现误报?这是一个例子:http://pastebin.com/Zydk9e6W (2认同)

bar*_*own 6

对于需要代码覆盖的私有方法(临时或永久),使用rspec-context-private gem临时在上下文中公开私有方法.

gem 'rspec-context-private'
Run Code Online (Sandbox Code Playgroud)

它的工作原理是为项目添加共享上下文.

RSpec.shared_context 'private', private: true do

  before :all do
    described_class.class_eval do
      @original_private_instance_methods = private_instance_methods
      public *@original_private_instance_methods
    end
  end

  after :all do
    described_class.class_eval do
      private *@original_private_instance_methods
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

然后,如果您将:private元数据作为元数据传递给describe块,则私有方法将在该上下文中公开.

class Example
  private def foo
    'bar'
  end
end

describe Example, :private do
  it 'can test private methods' do
    expect(subject.foo).not eq 'bar'
  end
end
Run Code Online (Sandbox Code Playgroud)