繁体   English   中英

在RSpec 3.2中存根实例变量

[英]Stubbing instance variables in RSpec 3.2

我在Rails中使用RSpec 3.2,想知道如果实例变量不能通过getter方法公开访问(例如,使用attr_accessor或类似方法),该如何对它们进行存根。

考虑下面的简单示例-

require 'rails_helper'

class A
  def initialize
    @x = 3
  end

  def add(n)
    sum = @x + n
    puts "Sum is #{sum}"
    sum
  end
end


RSpec.describe A do
  before(:all) do
    @a = A.new
  end

  it 'computes the sum correctly' do
    # For this test I want to stub the value of @x and return 5
    allow(@a).to receive(:x) { 5 }
    # 5 + 8 should return 13
    expect(@a.add(8)).to eq(13)
  end
end

在这种情况下,尝试对@x进行存根是不可能的,因为该类永远不会收到x的消息或方法调用。 RSpec输出确认了这一点-

Failures:

  1) A computes the sum correctly
     Failure/Error: allow(@a).to receive(:@x) { 5 }
       #<A:0x007fe6e66ab8d0 @x=3> does not implement: @x
     # ./spec/unit/test_spec.rb:25:in `block (2 levels) in <top (required)>'

我可以解决此通过使实例变量@x访问( attr_accesssor :x )和更换调用@xself.x ,但似乎哈克和我的更复杂的实现是不可能的。

是否有更好的方法来存根?

谢谢!

我认为这不是正确的做法。 Rspec应该测试类的接口行为,而不是内部实现。

由于不使用访问器,因此可以使用#instance_variable_set#instance_variable_get来操纵并获取实例变量。

获取和设置如下:

@a.instance_variable_set(:@x, 5)
@a.instance_variable_get(:@x)
#=> 5

在您的代码中:

@a.instance_variable_set(:@x, 5)
expect(@a.add(8)).to eq(13)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM