3

在 rspec-rails 中,我有一个名为“Customer”的 activerecord 模型。客户有_许多“互动”。我最近花了很多时间调试一些东西。我让它工作了,但我想出的答案对我来说真的没有意义。

以下代码(利用 RSpec 的“主题属性”)不起作用:

its(:interactions) { should_receive(:create) }

但这有效:

it "should call the 'create' method on interactions" do
  subject.interactions.should_receive(:create)
end

谁能解释为什么会这样?也许我误解了缩短方法语法的工作原理。我查看了文档,但没有提出任何充分的理由。

这是完整的代码:

describe Customer do

    ...other code ...

    describe "#migrate_interactions" do
      context "when a customer successfully migrates interactions from a lead" do

        subject { FactoryGirl.create(:customer) }
        let(:lead) { mock_model(Lead) }

        before :each do

          @lead_interaction = { :user_id            => 1, 
                                :interaction_type   => 'phone', 
                                :notes              => 'test',
                                :created_at         => Time.now
                              }

          lead.should_receive(:interactions).and_return([stub(@lead_interaction)])
        end

        its(:interactions) { should_receive(:create) }
        its(:interactions) { should_receive(:create).with(hash_including(@lead_interaction)) }

        after { subject.migrate_interactions lead }

      end
    end
end

Customer.rb 中的模型方法:

def migrate_interactions lead
  raise ArgumentError unless lead.respond_to? :interactions

  lead.interactions.each do |interaction|
    self.interactions.create({ :user_id          => interaction.user_id,
                               :interaction_type => interaction.interaction_type,
                               :notes            => interaction.notes,
                               :created_at       => interaction.created_at })
  end
end

谢谢!

- - - - - 编辑 - - - - -

我忘记包含使用 its(:interactions) { ... } 语法时出现的错误。这是错误:

1) Customer#migrate_interactions when a customer migrates interactions from a lead interactions 
 Failure/Error: its(:interactions) { should_receive(:create) }
   (#<RSpec::Core::ExampleGroup::Nested_2::Nested_6::Nested_3::Nested_1:0x0000000af10e78>).create(any args)
       expected: 1 times
       received: 0 times
 # ./spec/models/customer_spec.rb:100:in `block (4 levels) in <top (required)>'
4

1 回答 1

3

你试图做的事情是行不通的,因为 RSpec 的单行语法(例如it { should do_something })支持should但不支持should_receive. 这是我从未想过要添加的东西,因为它与我对消息期望的方法不一致,而且我认为它从未出现在功能请求中。

开发中有一个新的语法替代方案expect(object).to receive(message),它可能会打开通往 的大门it { should receive(message) },但我不确定(我不再运行该项目,也没有详细查看该代码)。如果您有兴趣,请查看(并加入对话)https://github.com/rspec/rspec-mocks/issues/153

HTH,大卫

于 2013-04-15T13:06:12.467 回答