いくつかのインスタンス変数といくつかのメソッドを持つクラスを考えます。一部のインスタンス変数は、_attr_reader
_および_attr_accessor
_を介してアクセス可能に設定されます。したがって、他はプライベートです。
一部のプライベートインスタンス変数は、いずれかのインスタンスメソッド内で設定され、別のメソッド内で読み取り/利用されます。
テストには、RSpecを使用しています。 Rubyが初めてで、すべてを正しくしたいので、テストをかなりきめ細かく定義しました。したがって、それぞれに1つのdescribe
ブロックがありますインスタンスメソッドは、それ自体がcontext
sとit
sのサブセットに分割されます。一般的な環境の前提条件は、before
で定義されます。
ただし、プライベート変数の1つを使用するが設定しないメソッドの1つをテストする場合、この変数を設定する他のメソッドを呼び出す必要があります。これはかなり太りすぎで、私にとってはモジュール式ではありません。
プライベートインスタンス変数を特定の値に強制する方法はありますか。 「ripping outObject::instance_eval(:var)
を使用したプライベートインスタンス変数の値」に似ています。
質問で答えたように、インスタンス変数を設定する最も簡単な方法は、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)
つかいます 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
私はちょうど子を作成し、アクセサーを追加することでそれを解決しました:
class HasSecrets
@muahaha
end
class TestMe < HasSecrets
attr_accessor(:muahaha)
end
def test_stuff
pwned = TestMe.new()
pwned.muahaha = 'calc.exe'
end