猴子在块之前用 mock in 修补

Monkey patching with mock in before block

这是最终起作用的:

# lib file
module SlackWrapper
  class << self
    def client
      @client ||= ::Slack::Web::Client.new
    end
  end
end

describe SlackWrapper do
  # test file
  before :each do
    $mock_client = double("slack client").tap do |mock|
      allow(mock).to receive(:channels_info) { channel_info }
    end

    module SlackWrapper
      class << self
        def client
          $mock_client
        end
      end
    end
  end

  describe "#should_reply?" do
    describe "while channel is paused" do
      it "is falsey" do
        SlackWrapper.pause_channel message.channel

        expect(
          SlackWrapper.should_reply? message
        ).to be_falsey
      end
    end

    describe "while channel is not paused" do
      it "is truthy" do
        expect(
          SlackWrapper.should_reply? message
        ).to be_truthy
      end
    end
  end
end

这个肯定感觉不对。但是,当测试为 运行 时,将 $mock_client 保留为本地变量会得到 undefined local variable,并将 double... 代码移动到 monkeypatch 中会得到 undefined method。当然,还有 monkeypatching。

正确的做法是什么?

您可以 stub 测试块或整个规范文件的 new 方法:

# test file

# you could also create a class double if you need its methods:
# https://relishapp.com/rspec/rspec-mocks/v/3-9/docs/verifying-doubles/using-a-class-double
let(:slack_client) { double("slack client") }

before(:each) do
  allow(::Slack::Web::Client).to receive(:new).and_return(slack_client)
end

# simple example:
it "checks slack client method to be a double" do
  expect(SlackWrapper.client).to be(slack_client)
end