如何设置方法测试中使用的私有实例变量?

Tor*_*örn 45 ruby testing rspec access-specifier

给定一个带有几个实例变量和一些方法的类.一些实例变量可通过attr_reader和设置访问attr_accessor.因此其他人是私人的.
某些私有实例变量在其中一个实例方法中设置,并在另一个方法中读取/使用.

为了测试我正在使用RSpec.由于我还是Ruby的新手,并且想要把所有事情都搞定,我将我的测试定义得相当精细.因此,我describe为每个实例方法都有一个块,它们本身被划分为contexts和its 的子集.一般环境先决条件定义为before.

但是,当测试其中一个方法,即使用但未设置其中一个私有变量时,我需要调用另一个方法,即设置此变量.这似乎相当超重,对我来说不是模块化的.

有没有办法强制私有实例变量到某个值.类似于" 剥离 "私有实例变量的值Object::instance_eval(:var).

Ali*_*kau 84

在您的问题中回答,设置实例变量的最简单方法是使用instance_eval方法:

obj.instance_eval('@a = 1')
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用instance_variable_set:

obj.instance_variable_set(:@a, 1)
Run Code Online (Sandbox Code Playgroud)

但我不建议在你的规格中这样做.规范都是关于测试对象的行为,通过破坏类封装测试行为instance_eval将使您的测试更加脆弱和依赖于实现.

对象状态隔离的替代方法是存根访问器方法:

class UnderTest
  attr_accessor :a

  def test_this
    do_something if a == 1
  end
end

#in your test
under_test = UnderTest.new
under_test.stub(:a).and_return(1)
Run Code Online (Sandbox Code Playgroud)


rob*_*rit 8

用途instance_variable_set:

class SomeClass
  attr_reader :hello
  def initialize
    @hello = 5
  end
  # ...
end

a = SomeClass.new
a.hello    # => 5

a.instance_variable_set("@hello", 7)
a.hello    # => 7
Run Code Online (Sandbox Code Playgroud)