如何rspec模拟ruby rails logger类

时间:2011-11-23 22:15:57

标签: ruby-on-rails ruby logging rspec mocking

您好我并尝试rspec模拟以下类:

    class Person
      def initialize(personid)
        Rails.logger.debug "Creating person with id #{personid}"
      end
    end

使用此:

require 'spec_helper'
  describe Person do
    describe "#initialize" do
      let(:rails_mock) { double("Rails").as_null_object }
      let(:logger_mock) { double("Rails.logger").as_null_object }

      it "logs a message" do
        rails_mock.stub(:logger).and_return(logger_mock)
        logger_mock.should_receive(:debug)
        Person.new "dummy"
      end
   end
end

并收到此消息:

  

RSpec :: Mocks :: MockExpectationError :( Double“Rails.logger”)。debug(any args)
      预计:1次
      收到:0次

任何帮助都会很棒!

3 个答案:

答案 0 :(得分:5)

我会这样做:

Rails.stub_chain(:logger, :debug).and_return(logger_mock)

不要忘记在测试结束时取消存储:

Rails.unstub(:logger)

答案 1 :(得分:1)

存根不起作用,因为这些存根没有链接到实际代码。它应该是这样的:

require 'spec_helper'
  describe Person do
    describe "#initialize" do
      let(:logger_mock) { double("Rails.logger").as_null_object }

      it "logs a message" do
        Rails.stub(:logger).and_return(logger_mock)
        logger_mock.should_receive(:debug)
        Person.new "dummy"
      end
   end
end

对于OP:如果您只想设置日志记录的期望,则根本不需要存根整个记录器类。你可以做到

Rails.logger.should_receive(:debug)

奖励:如果您只想存根,那么不会发生任何记录,请执行以下操作:

Rails.logger.stub(:add){ true }

答案 2 :(得分:0)

以下是使用部分双精度的对此问题的更新答案:

let(:personid) { 'dummy' }

before do
  allow(Rails.logger).to receive(:debug).and_return nil
  Person.new(personid)
end

it { expect(Rails.logger).to have_received(:debug).with(a_string_matching(personid)) }

RSpec不需要为您做任何事情。