给定一个包含几个实例变量和一些方法的类。某些实例变量可通过attr_reader
和attr_accessor
设置。因此其他人都是私人的
某些私有实例变量在其中一个实例方法中设置,并在另一个方法中读取/使用。
测试我正在使用RSpec。由于我还是Ruby的新手,并且想要把所有事情都搞定,我将我的测试定义得相当精细。因此,我为每个实例方法都有一个describe
块,它们本身被划分为context
s和it
s的子集。一般环境先决条件由before
定义。
但是,当测试其中一个方法,即使用但未设置其中一个私有变量时,我需要调用另一个方法,即设置此变量。这对我来说似乎相当超重而且不模块化。
是否有一种方法可以将私有实例变量强制转换为某个值。与“剥离”类似,私有实例变量的值为Object::instance_eval(:var)
。
答案 0 :(得分:84)
在您的问题中回答,设置实例变量的最简单方法是使用instance_eval
方法:
obj.instance_eval('@a = 1')
另一种方法是使用instance_variable_set:
obj.instance_variable_set(:@a, 1)
但我不建议在你的规格中这样做。规范是关于测试对象行为的,并且通过使用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)
答案 1 :(得分: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
答案 2 :(得分:0)
我只是通过创建一个孩子并添加一个访问器来解决它:
class HasSecrets
@muahaha
end
class TestMe < HasSecrets
attr_accessor(:muahaha)
end
def test_stuff
pwned = TestMe.new()
pwned.muahaha = 'calc.exe'
end