【问题标题】:RSpec transaction test persists changes to instance variable in before(:each)RSpec 事务测试在 before(:each) 中持久化对实例变量的更改
【发布时间】:2018-01-15 09:01:53
【问题描述】:

所以...

我有一个 RSpec 测试问题,我正在尝试配置特定设置(不创建新数据,但修改实例数据),并且在运行测试用例后,数据不会恢复。请看下面一个简单的例子,注意 foo 是一个 ActiveRecord 对象...... 需要'rails_helper'

RSpec.describe My::Code do
  before(:context) do
    @foo = FactoryGirl.create(:foo)
  end

  after(:context) do
    @foo.destroy!
  end

  let(:foo) { @foo.clone }

  describe 'something' do
    # Imagine `something` just returns foo.bar, which is an over-
    # simplification, but gives you an idea of the problem I am seeing
    subject { My::Code.something(foo) }

    context 'when foo has different property value' do
      before(:each) do
        foo.bar = false
      end

      it { is_expected_to be(false) }
    end

    context 'when foo has original property value' do
      # This will fail, as foo's bar property is still false
      it { is_expected_to be(true) }
    end
  end

...这是我的情况的要点,我无法弄清楚为什么 RSpec 没有回滚。我的一些rails_helper 文件...

config.use_transactional_fixtures = true
...
config.around(:each) do |example|
  DatabaseCleaner.cleaning do
    example.run
  end
end

...任何见解都非常感谢。

【问题讨论】:

  • 如果我将 let 绑定更改为 let(:foo) { @foo.reload.clone },一切都会按预期进行,但似乎我不需要这个。

标签: ruby-on-rails ruby activerecord rspec


【解决方案1】:

在 Ruby on Rails 中,使用 clone,这似乎是预期的行为:

与 Ruby 的 clone 方法相同。这是一个“浅”的副本。 请注意,您的属性不会被复制。这意味着修改克隆的属性将修改原始属性,因为它们都指向相同的属性哈希。如果您需要属性哈希的副本,请使用dup 方法。

强调我的。因此,通过使用clone,您仍然指向相同的属性散列并且修改一个会修改另一个。

正如您所发现的,您可以reload 删除所有更改的对象,或者您可以调用dup 而不是clone

请注意,这是一个“浅”副本,因为它仅复制对象的属性,而不是其关联。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 2012-12-24
    • 2021-09-28
    • 2013-05-13
    相关资源
    最近更新 更多