0

我开始尝试在我的代码中加入更多测试,但我碰壁了。

我的模型看起来像这样

class Image < ActiveRecord:Base
  before_create :do_something_general
  before_update :do_something_on_update, :do_something_general

  belongs_to :captureable, polymorphic: true

  mount_uploader :image, SomeUploader
  ...
end

我的 rspec 看起来像

describe SomeModel do
  before :each do
     @image = FactoryGirl.create(:image)
  end
  ...
  describe "moving image" do
     context "change the parent of the image" do
         it "moves" do
            new_parent = FactoryGirl.create(:parent)
            current_file_path = @image.image.file.path
            @image.captureable = new_parent
            @image.save!
            @image.image.file.path.should_not == current_file_path
         end
      end
  end
end

当我第一次创建图像时,它将存储在依赖于其父级的文件树结构中。当父级更改时,应该移动图像,这是通过 before_update 回调:do_something_on_update 完成的。我的测试应该验证当 Image 的父级更改时,它位于一个新位置。

问题是,当@image.save.should be_valid因为 :do_something_general 在 :do_something_on_update 之前运行而返回异常时(顺序很重要)。似乎 rspec 认为我正在创建一个新对象(使用调试器我检查过对象 id 在修改它时没有改变),因此运行 before_create 而不是 before_update。

编辑:似乎 before_update 正在工作,但仅限于类中的回调方法,而不是模块中的回调方法。在这种情况下, :do_something_on_update 位于包含的模块中。结束编辑

当我在开发模式下的控制台中尝试此操作时,它按预期工作。

其他需要注意的事项:我使用 Carrierwave 进行上传(图像列是载波上传器),当调用 :image 工厂时,它还会创建几个父对象和祖父对象。使用 Rspec 2.10、Rails 3.2.8、Ruby 1.9.3

期待您的回复。

谢谢。

4

1 回答 1

0

我预计image.save.should be_valid会失败,因为它将调用image.save返回 true 或 false,然后它将调用#valid?该布尔结果,这可能会失败。

您可能会考虑这样编写测试:

describe SomeModel do
  let(:image) { FactoryGirl.create(:image) }

  context "when changing the parent of the image" do
    let(:parent_change) { lambda {
      image.captureable = FactoryGirl.create(:parent)
      image.save!
    } }

    it "updates the image's path" do
      expect parent_change.to change { image.image.file.path }
    end
  end
end

这可确保您在测试中只有一个断言(文件路径正在更改),并且如果保存失败,它将引发异常。

于 2012-11-30T00:09:51.350 回答