繁体   English   中英

使用 Rspec 对链式方法进行存根

[英]Stubbing Chained Methods with Rspec

我想调用一个只返回一条记录的named_scope,但是named_scope返回一个数组,这没什么大不了的,因为我可以用.first链接它:

Model.named_scope(param).first

这很有效,我正在努力解决的是如何存根链式调用。 有没有人有关于我将如何使用 Rspec mocking 实现这一目标的参考或答案?

我想通了。

Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))

这让我可以打电话给我的 controller:

@client = Client.named_scope(param).first

它有效,但有更好的解决方案吗?

编辑:

rspec 1.2.6 的发布允许我们使用 stub_chain 意味着它现在可以是:

Client.stub_chain(:named_scope, :chained_call).and_return(@clients = [mock(Client)])

这是我的头等大事,一如既往地检查 api 了解详情:)

这个问题已经很老了,因此在如何进行存根方面几乎没有改进。 现在您可以使用 stub_chain 方法来存根方法调用链。 例如:

@client = Client.named_scope(param).first

可以存根:

Client.stub_chain(:named_scope,:first).and_return(@client = mock(Client))

stub_chaining 的更多示例:

describe "stubbing a chain of methods" do
  subject { Object.new }

  context "given symbols representing methods" do
    it "returns the correct value" do
      subject.stub_chain(:one, :two, :three).and_return(:four)
      subject.one.two.three.should eq(:four)
    end
  end

  context "given a string of methods separated by dots" do
    it "returns the correct value" do
      subject.stub_chain("one.two.three").and_return(:four)
      subject.one.two.three.should eq(:four)
    end
  end
end

或者请看一下:

rspecs 万岁:!! :)

更好的版本

Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))

将会:

Client.should_receive(:named_scope).with(param).and_return do
  record = mock_model(Comm)
  record.should_receive(:do_something_else)
  [record]  
end

我想这是在 controller 规范中?

您自己的建议应该可以正常工作。 另一种可能性是在 model 中移动 named_scope 调用,以完全避免该问题。 这也符合“胖模型,瘦控制器”的建议。

我认为您已经通过将查询放入可以重用的名为 scope 的查询中完成了精简的 controller 事情。 这是我开始使用命名范围之前使用的一些代码。

  def mock_comm(stubs={})
    @mock_comm ||= mock_model(Comm, stubs)
  end

  describe "responding to GET index" do

    it "should expose all comms as @comms" do
      Comm.should_receive(:find).with(:all).and_return([mock_comm])
      get :index
      assigns[:comms].should == [mock_comm]
    end
# ...

我可能会编写与您已经编写的代码非常相似的代码,但可能会将其放在允许我重用它的帮助程序中。 另一件事是使用不同的 mocking 框架,它可能会给你更多的控制权。 看看 Ryan Bates 在 RSpec 上的 railscast - 现在有点老了,但仍然有一些好主意。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM