RSpec类变量测试



我正在使用RSpec测试gem中的类级实例变量(和setter)。我需要测试以下内容:

  1. 如果从未使用setter,则提供正确的默认值。
  2. 可以通过设置器成功更新变量。

显然这里有一个运行顺序问题。如果我使用setter更改值,我就会丢失关于默认值的记忆。我可以在setter测试之前将其保存到一个变量中,然后在结束时重置该值,但这只有在所有setter测试都遵循相同的实践时才能保护我。

测试变量默认值的最佳方法是什么?

下面是一个简单的例子:

class Foo
  class << self
    attr_accessor :items
  end
  @items = %w(foo bar baz) # Set the default
  ...
end
describe Foo do
  it "should have a default" do
    Foo.items.should eq(%w(foo bar baz))
  end
  it "should allow items to be added" do
    Foo.items << "kittens"
    Foo.items.include?("kittens").should eq(true)
  end
end
class Foo
  DEFAULT_ITEMS = %w(foo bar baz)
  class << self
    attr_accessor :items
  end
  @items = DEFAULT_ITEMS
end
describe Foo do
  before(:each) { Foo.class_variable_set :@items, Foo::DEFAULT_ITEMS }
  it "should have a default" do
    Foo.items.should eq(Foo::DEFAULT_ITEMS)
  end
  it "should allow items to be added" do
    Foo.items << "kittens"
    Foo.items.include?("kittens").should eq(true)
  end
end
或者更好的方法是重新加载 类
describe 'items' do
  before(:each) do
    Object.send(:remove_const, 'Foo')
    load 'foo.rb'
  end
end

如果你的类有你想测试的内部状态,我发现使用class_variable_get是一个很好的方法。这并不要求您公开类中的任何变量,因此类可以保持不变。

it 'increases number by one' do
    expect(YourClass.class_variable_get(:@@number)).to equal(0)
    YourClass.increase_by_one()
    expect(YourClass.class_variable_get(:@@number)).to equal(1)
end

我知道这不是你的问题所要求的,但它在标题中,这让我在这里。

我发现这个问题追求一个稍微不同的问题——在rspec示例之间清除缓存的类变量。

在模块中,我有一个昂贵的类配置,我像这样缓存:

module Thingamizer
  def config
    @config ||= compute_config_the_hard_way()
  end
end
class Thing
   extend Thingamizer
end

在我对Thing的rspec测试中,compute_config_the_hard_way只被第一次调用。后续调用使用缓存的版本,即使我模拟compute_config_the_hard_way在其他测试中返回不同的东西。

我通过在每个示例之前清除@config来解决这个问题:

 before { Thing.instance_variable_set(:@config, nil) }
@config是一个变量,而不是一个实例变量。我试了很多class_variable_set的变体,都没有运气。 这里的问题是Thing(类)实际上是class的实例。因此,在类方法中似乎是类变量的实际上是一个实例变量,在class(即Thing)的实例中。一旦我明白了这个想法,使用instance_variable_set而不是class_variable_set就很有意义了。

参见在类方法中使用实例变量- Ruby中讨论类变量作为实例变量

相关内容

  • 没有找到相关文章

最新更新