メインコンテンツまでスキップ

受信回数

メッセージを期待する際に、メッセージが受信される回数を指定することができます。

  • expect(...).to receive(...).once
  • expect(...).to receive(...).twice
  • expect(...).to receive(...).exactly(n).time
  • expect(...).to receive(...).exactly(n).times
  • expect(...).to receive(...).at_least(:once)
  • expect(...).to receive(...).at_least(:twice)
  • expect(...).to receive(...).at_least(n).time
  • expect(...).to receive(...).at_least(n).times
  • expect(...).to receive(...).at_most(:once)
  • expect(...).to receive(...).at_most(:twice)
  • expect(...).to receive(...).at_most(n).time
  • expect(...).to receive(...).at_most(n).times

受信回数を指定しない場合、デフォルトで once となります。

背景

次の内容で "lib/account.rb" という名前のファイルがあるとします:

class Account
def initialize(logger)
@logger = logger
end

def open
@logger.account_opened
end
end

パスする例

次の内容で "spec/account_spec.rb" という名前のファイルがあるとします:

require 'account'

RSpec.describe Account do
let(:logger) { double("Logger") }
let(:account) { Account.new(logger) }

example "once" do
expect(logger).to receive(:account_opened).once
account.open
end

example "twice" do
expect(logger).to receive(:account_opened).twice
account.open
account.open
end

example "exactly(n).time" do
expect(logger).to receive(:account_opened).exactly(1).time
account.open
end

example "exactly(n).times" do
expect(logger).to receive(:account_opened).exactly(3).times
account.open
account.open
account.open
end

example "at_least(:once)" do
expect(logger).to receive(:account_opened).at_least(:once)
account.open
account.open
end

example "at_least(:twice)" do
expect(logger).to receive(:account_opened).at_least(:twice)
account.open
account.open
account.open
end

example "at_least(n).time" do
expect(logger).to receive(:account_opened).at_least(1).time
account.open
end

example "at_least(n).times" do
expect(logger).to receive(:account_opened).at_least(3).times
account.open
account.open
account.open
account.open
end

example "at_most(:once)" do
expect(logger).to receive(:account_opened).at_most(:once)
end

example "at_most(:twice)" do
expect(logger).to receive(:account_opened).at_most(:twice)
account.open
end

example "at_most(n).time" do
expect(logger).to receive(:account_opened).at_most(1).time
account.open
end

example "at_most(n).times" do
expect(logger).to receive(:account_opened).at_most(3).times
account.open
account.open
end
end

rspec spec/account_spec.rb を実行すると、

すべての例がパスするはずです。

失敗する例

次の内容で "spec/account_spec.rb" という名前のファイルがあるとします:

require 'account'

RSpec.describe Account do
let(:logger) { double("Logger") }
let(:account) { Account.new(logger) }

example "once" do
expect(logger).to receive(:account_opened).once
account.open
account.open
end

example "twice" do
expect(logger).to receive(:account_opened).twice
account.open
end

example "exactly(n).times" do
expect(logger).to receive(:account_opened).exactly(3).times
account.open
account.open
end

example "at_least(:once)" do
expect(logger).to receive(:account_opened).at_least(:once)
end

example "at_least(:twice)" do
expect(logger).to receive(:account_opened).at_least(:twice)
account.open
end

example "at_least(n).times" do
expect(logger).to receive(:account_opened).at_least(3).times
account.open
account.open
end

example "at_most(:once)" do
expect(logger).to receive(:account_opened).at_most(:once)
account.open
account.open
end

example "at_most(:twice)" do
expect(logger).to receive(:account_opened).at_most(:twice)
account.open
account.open
account.open
end

example "at_most(n).times" do
expect(logger).to receive(:account_opened).at_most(3).times
account.open
account.open
account.open
account.open
end
end

rspec spec/account_spec.rb --order defined を実行すると、

すべての例が失敗し、以下の出力が生成されるはずです:

| 期待: 1回の引数なしでの受信 | | 受信: 2回 | | | | 期待: 2回の引数なしでの受信 | | 受信: 1回の引数なしでの受信 | | | | 期待: 3回の引数なしでの受信 | | 受信: 2回の引数なしでの受信 | | | | 期待: 1回以上の引数なしでの受信 | | 受信: 0回の引数なしでの受信 | | | | 期待: 2回以上の引数なしでの受信 | | 受信: 1回の引数なしでの受信 | | | | 期待: 3回以上の引数なしでの受信 | | 受信: 2回の引数なしでの受信 | | | | 期待: 1回以下の引数なしでの受信 | | 受信: 2回 | | | | 期待: 2回以下の引数なしでの受信 | | 受信: 3回 | | | | 期待: 3回以下の引数なしでの受信 | | 受信: 4回 |

Sure, please paste the Markdown content that you would like me to translate into Japanese.