0

paranoid2 gemを使用するモデルの RSpec テストに取り組んでいます。これはある種のパラノイアまたはacts_as_paranoidです - .delete と .destroy およびその他のものを、(forced: true)パラメーターで強制するまでデータを削除するのではなく、データを削除済みとしてマークする独自のバージョンで上書きします。

私のアプリは問題なく動作しますが、rspec のみに問題があります。

仕様/モデル/slide_spec.rb:

describe Slide do

 let (:slide) { build(:slide) }

  describe "after .destroy(force: true)" do
   before do      
      slide.save
      slide.destroy(force: false)      
   end
    it "is invisible" do
      expect{slide.destroy(force: true)}.to_not change(Slide, :count)
    end
    it "visible if .only_deleted" do
      expect{slide.destroy(force: true)}.to change(Slide.only_deleted, :count).by(-1)
    end    
    it "visible if .with_deleted" do
      expect{slide.destroy(force: true)}.to change(Slide.with_deleted, :count).by(-1)
    end
  end
 end

rspec 出力:

  after .destroy(force: true)
    visible if .with_deleted (FAILED - 1)
    visible if .only_deleted (FAILED - 2)
    is invisible (FAILED - 3)

Failures:

  1) Slide after .destroy(force: true) visible if .with_deleted
     Failure/Error: expect{slide.destroy(force: true)}.to change(Slide.with_deleted, :count).by(-1)
     RuntimeError:
       can't modify frozen Hash
     # ./spec/models/slide_spec.rb:52:in `block (4 levels) in <top (required)>'
     # ./spec/models/slide_spec.rb:52:in `block (3 levels) in <top (required)>'

  2) same as above

  3) same sa above

/アプリ/モデル/slide.rb:

class Slide < ActiveRecord::Base
    paranoid
    ...
4

1 に答える 1

4

freezeこれは、モデルで destroy を呼び出した後、Rails が内部属性ハッシュを でマークするために発生します。この凍結されたハッシュは、オブジェクトがそれ以上変更されないようにします: は後でdestroy(force: true)を削除したい、 はデータベースからの新しい値でいくつかの属性をオーバーライドしたい - どちらも失敗しますidreload

この問題を回避する唯一の方法は、オブジェクトを手動でリロードすることです。

describe "after .destroy(force: true)" do
  before do
    slide.save
    slide.destroy(force: false)
    @slide = Slide.with_deleted.find(slide.id)  # manual reload
  end
  it "is invisible" do
    expect{@slide.destroy(force: true)}.to_not change(Slide, :count)
  end
  it "visible if .only_deleted" do
    expect{@slide.destroy(force: true)}.to change(Slide.only_deleted, :count).by(-1)
  end
  it "visible if .with_deleted" do
    expect{@slide.destroy(force: true)}.to change(Slide.with_deleted, :count).by(-1)
  end
end
于 2014-04-04T13:36:04.443 に答える