4

如何使用 rspec 测试这样的代码?

Foo.create! do |foo|
  foo.description = "thing"
end

我不想测试对象是否已创建——我想测试是否使用正确的对象调用了正确的方法。相当于测试这个:

Foo.create!(description: "thing")

有了这个:

Foo.should_receive(:create!).with(description: "thing")
4

3 回答 3

1

这就是你所追求的吗?

it "sets the description" do
  f = double
  Foo.should_receive(:create!).and_yield(f)
  f.should_receive(:description=).with("thing")

  Something.method_to_test
end
于 2012-11-01T20:28:42.190 回答
0
Foo.count.should == 1
Foo.first.description.should == 'thing'
于 2012-11-01T07:03:10.843 回答
0

这是一种组合方法,它融合了@antiqe 和@Fitzsimmons 的最佳答案。不过,它要冗长得多。

这个想法是以更像 AR::Base.create 的方式模拟 Foo.create。首先,我们定义一个辅助类:

class Creator
  def initialize(stub)
    @stub = stub
  end

  def create(attributes={}, &blk)
    attributes.each do |attr, value|
      @stub.public_send("#{attr}=", value)
    end

    blk.call @stub if blk

    @stub
  end
end

然后我们可以在我们的规范中使用它:

it "sets the description" do
  f = stub_model(Foo)
  stub_const("Foo", Creator.new(f))

  Something.method_to_test

  f.description.should == "thing"
end

您也可以使用FactoryGirl.build_stubbed代替stub_model. 但是,您不能使用mock_model,mock或者double因为您会再次遇到相同的问题。

现在,您的规范将通过以下任何代码片段:

Foo.create(description: "thing")

Foo.create do |foo|
  foo.descrption = "thing"
end

foo = Foo.create
foo.descrption = "thing"

反馈表示赞赏!

于 2012-11-20T16:17:38.167 回答