模拟类主键

时间:2014-03-05 18:49:18

标签: ruby-on-rails ruby unit-testing rspec mocking

在我加入之前,我有一段代码在项目中:

def create_message!
  Message.create(
        :sender_id => @sending_user.id,
        :receiver_id => recipient_user.id,
        :body => @body,
        :read => false
      )
end

我们最近在我们的项目中添加了publicactivity gem,因此我修改了代码:

def create_message!
    message =  Message.create(
            :sender_id => @sending_user.id,
            :receiver_id => recipient_user.id,
            :body => @body,
            :read => false
          )

    message.create_activity :create, owner: @sending_user, recipient: recipient_user
    message 
    end

但现在测试失败了:

1) MandrillEvent parses inbound responses
     Failure/Error: message = MandrillEvent.process(@msgs[0])
     NoMethodError:
       undefined method `primary_key' for RSpec::Mocks::Mock:Class
     # ./app/models/mandrill_event.rb:59:in `create_message!'
     # ./app/models/mandrill_event.rb:93:in `process'
     # ./spec/models/mandrill_event_spec.rb:40:in `block (2 levels) in <top (required)>'

这是我的测试:

describe MandrillEvent do
  before do
    MyApp::Application.stub_chain(:config, :mandrill_email_domain).and_return('example.com')
    json = File.read 'spec/support/assets/mandrill_inbound.json'
    @msgs = JSON.parse json

    sending_user = double("User")
    sending_user.stub(:id) { 1 }
    receiving_user = double("User")
    receiving_user.stub(:id) { 2 }
    User.stub(:find_by_email) { sending_user }
    match = double("Match")
    match.stub(:id) { 1 }
    match.stub(:involves?){ true }
    match.stub(:other_user){ receiving_user }
    Match.stub(:find_by_uuid) { match }
    Message.any_instance.stub(:send_notification)
  end

  describe MandrillEvent::EmailMessage do
    subject { MandrillEvent::EmailMessage.new(@msgs[0]['msg']) }

    it { should respond_to(:body) }
    it { should respond_to(:from) }
    it { should respond_to(:sending_user) }
    it { should respond_to(:matched?) }

    it 'checks matches' do
      subject.matched?.should be_true
    end
  end

  it 'parses inbound responses' do
    message = MandrillEvent.process(@msgs[0])
    message.should_not be_nil
    message.body.should_not be_nil
  end

我的代码如何更改导致此错误:

undefined method `primary_key' for RSpec::Mocks::Mock:Class

我应该对测试做出哪些修改?为什么测试会查找primary_key列?

1 个答案:

答案 0 :(得分:1)

我相信当您致电message.create_activity并通过所有者double("User")时会发生此错误。

您可以尝试将primary_key添加到double:

sending_user = double("User")
sending_user.stub(:primary_key) { 1 }
# ...

sending_user = double("User", primary_key: 1)

或者通过将其设为null_object

来使你的双倍宽容
sending_user = double("User").as_null_object
sending_user.stub(:id) { 1 }