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

RSpecの期待値

RSpec::Expectationsを使用すると、例でオブジェクトの期待される結果を表現することができます。

expect(account.balance).to eq(Money.new(37.42, :USD))

インストール

RSpecを使用してrspec-expectationsを使用する場合は、単にrspec gemをインストールし、RubyGemsがrspec-expectationsも一緒にインストールします(rspec-coreとrspec-mocksも):

gem install rspec

mainブランチで実行したいですか?依存するRSpecリポジトリも含める必要があります。次の内容をGemfileに追加してください:

%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main'
end

Test::Unit、Minitest、またはCucumberなどの他のツールでrspec-expectationsを使用したい場合は、直接インストールすることもできます:

gem install rspec-expectations

基本的な使用法

以下はrspec-coreを使用した例です:

RSpec.describe Order do
it "sums the prices of the items in its line items" do
order = Order.new
order.add_entry(LineItem.new(:item => Item.new(
:price => Money.new(1.11, :USD)
)))
order.add_entry(LineItem.new(:item => Item.new(
:price => Money.new(2.22, :USD),
:quantity => 2
)))
expect(order.total).to eq(Money.new(5.55, :USD))
end
end

describeメソッドとitメソッドはrspec-coreから提供されます。OrderLineItemItemMoneyクラスは_あなたの_コードから取得します。例の最後の行は期待される結果を表現しています。order.total == Money.new(5.55, :USD)の場合、例は合格します。そうでない場合は、次のようなメッセージで失敗します:

    expected: #<Money @value=5.55 @currency=:USD>
got: #<Money @value=1.11 @currency=:USD>

組み込みのマッチャー

等価性

expect(actual).to eq(expected)  # actual == expectedの場合に合格
expect(actual).to eql(expected) # actual.eql?(expected)の場合に合格
expect(actual).not_to eql(not_expected) # not(actual.eql?(expected))の場合に合格

注意:新しいexpect構文はもはや==マッチャーをサポートしていません。

同一性

expect(actual).to be(expected)    # actual.equal?(expected)の場合に合格
expect(actual).to equal(expected) # actual.equal?(expected)の場合に合格

比較

expect(actual).to be >  expected
expect(actual).to be >= expected
expect(actual).to be <= expected
expect(actual).to be < expected
expect(actual).to be_within(delta).of(expected)

正規表現

expect(actual).to match(/expression/)

注意:新しいexpect構文はもはや=~マッチャーをサポートしていません。

タイプ/クラス

expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected
expect(actual).to be_a(expected) # passes if actual.kind_of?(expected)
expect(actual).to be_an(expected) # an alias for be_a
expect(actual).to be_a_kind_of(expected) # another alias

真偽値

expect(actual).to be_truthy   # passes if actual is truthy (not nil or false)
expect(actual).to be true # passes if actual == true
expect(actual).to be_falsy # passes if actual is falsy (nil or false)
expect(actual).to be false # passes if actual == false
expect(actual).to be_nil # passes if actual is nil
expect(actual).to_not be_nil # passes if actual is not nil

エラーの予想

expect { ... }.to raise_error
expect { ... }.to raise_error(ErrorClass)
expect { ... }.to raise_error("message")
expect { ... }.to raise_error(ErrorClass, "message")

例外の予想

expect { ... }.to throw_symbol
expect { ... }.to throw_symbol(:symbol)
expect { ... }.to throw_symbol(:symbol, 'value')

ブロックの実行

expect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args

expect { |b| yield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yielded

expect { |b| 5.tap(&b) }.to yield_with_args(5)
expect { |b| 5.tap(&b) }.to yield_with_args(Integer)
expect { |b| "a string".tap(&b) }.to yield_with_args(/str/)

expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)
expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2])

述語マッチャー

expect(actual).to be_xxx         # actual.xxx? が true の場合にパスする
expect(actual).to have_xxx(:arg) # actual.has_xxx?(:arg) が true の場合にパスする

範囲 (Ruby >= 1.9 のみ)

expect(1..10).to cover(3)

コレクションのメンバーシップ

# exact order, entire collection
expect(actual).to eq(expected)

# exact order, partial collection (based on an exact position)
expect(actual).to start_with(expected)
expect(actual).to end_with(expected)

# any order, entire collection
expect(actual).to match_array(expected)

# You can also express this by passing the expected elements
# as individual arguments
expect(actual).to contain_exactly(expected_element1, expected_element2)

# any order, partial collection
expect(actual).to include(expected)

expect([1, 2, 3]).to eq([1, 2, 3])            # Order dependent equality check
expect([1, 2, 3]).to include(1) # Exact ordering, partial collection matches
expect([1, 2, 3]).to include(2, 3) #
expect([1, 2, 3]).to start_with(1) # As above, but from the start of the collection
expect([1, 2, 3]).to start_with(1, 2) #
expect([1, 2, 3]).to end_with(3) # As above but from the end of the collection
expect([1, 2, 3]).to end_with(2, 3) #
expect({:a => 'b'}).to include(:a => 'b') # Matching within hashes
expect("this string").to include("is str") # Matching within strings
expect("this string").to start_with("this") #
expect("this string").to end_with("ring") #
expect([1, 2, 3]).to contain_exactly(2, 3, 1) # Order independent matches
expect([1, 2, 3]).to match_array([3, 2, 1]) #

# Order dependent compound matchers
expect(
[{:a => 'hash'},{:a => 'another'}]
).to match([a_hash_including(:a => 'hash'), a_hash_including(:a => 'another')])

should 構文

expect 構文に加えて、rspec-expectations は should 構文も引き続きサポートしています:

actual.should eq expected
actual.should be > 3
[1, 2, 3].should_not include 4

should 構文とその使用方法の詳細については、こちらの詳細情報を参照してください。

複合マッチャー式

andor を使用して複合マッチャー式を作成することもできます:

expect(alphabet).to start_with("a").and end_with("z")
expect(stoplight.color).to eq("red").or eq("green").or eq("yellow")

マッチャーの組み合わせ

多くの組み込みマッチャーは、オブジェクトやデータ構造の必要な要素のみを柔軟に指定するために、マッチャーを引数として受け取るように設計されています。さらに、組み込みのマッチャーは、別のマッチャーの引数として使用される場合に、より適切な表現を提供する1つ以上のエイリアスを持っています。

expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) )

expect { s = "barn" }.to change { s }
.from( a_string_matching(/foo/) )
.to( a_string_matching(/bar/) )

expect(["barn", 2.45]).to contain_exactly(
a_value_within(0.1).of(2.5),
a_string_starting_with("bar")
)

expect(["barn", "food", 2.45]).to end_with(
a_string_matching("foo"),
a_value > 2
)

expect(["barn", 2.45]).to include( a_string_starting_with("bar") )

expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/))

hash = {
:a => {
:b => ["foo", 5],
:c => { :d => 2.05 }
}
}

expect(hash).to match(
:a => {
:b => a_collection_containing_exactly(
a_string_starting_with("f"),
an_instance_of(Integer)
),
:c => { :d => (a_value < 3) }
}
)

expect { |probe|
[1, 2, 3].each(&probe)
}.to yield_successive_args( a_value < 2, 2, a_value > 2 )

rspec-core の外での使用方法

ライブラリの一部のみを使用したい場合でも、常に rspec/expectations をロードする必要があります:

require 'rspec/expectations'

その後、任意のクラスに RSpec::Matchers を単純にインクルードします:

class MyClass
include RSpec::Matchers

def do_something(arg)
expect(arg).to be > 0
# do other stuff
end
end

他にも参照してください