RSpec (Legacy) 2.5.0以降
WARNING
この機能は非推奨であり、後方互換性のためにのみ維持されます。 新しいテストには新しいテストAPIの使用を推奨します。 段階的な手順についてはマイグレーションガイドを参照してください。
インストール
require "servactory/test_kit/rspec/helpers"
require "servactory/test_kit/rspec/matchers"RSpec.configure do |config|
config.include Servactory::TestKit::Rspec::Helpers
config.include Servactory::TestKit::Rspec::Matchers
# ...
end例
構造
.call!またはcall:subject;validations:inputs;internals;outputs;
when required data for work is valid:be_success_service;have_output.
when required data for work is invalid:be_failure_service.
ファイル
RSpec.describe UsersService::Create, type: :service do
describe ".call!" do
subject(:perform) { described_class.call!(**attributes) }
let(:attributes) do
{
first_name:,
middle_name:,
last_name:
}
end
let(:first_name) { "John" }
let(:middle_name) { "Fitzgerald" }
let(:last_name) { "Kennedy" }
describe "validations" do
describe "inputs" do
it do
expect { perform }.to(
have_input(:first_name)
.valid_with(attributes)
.type(String)
.required
)
end
it do
expect { perform }.to(
have_input(:middle_name)
.valid_with(attributes)
.type(String)
.optional
)
end
it do
expect { perform }.to(
have_input(:last_name)
.valid_with(attributes)
.type(String)
.required
)
end
end
describe "outputs" do
it do
expect(perform).to(
have_output(:full_name)
.instance_of(String)
)
end
end
end
context "when required data for work is valid" do
it { expect(perform).to be_success_service }
it do
expect(perform).to(
have_output(:full_name)
.contains("John Fitzgerald Kennedy")
)
end
describe "even if `middle_name` is not specified" do
let(:middle_name) { nil }
it do
expect(perform).to(
have_output(:full_name)
.contains("John Kennedy")
)
end
end
end
end
endclass UsersService::Create < ApplicationService::Base
input :first_name, type: String
input :middle_name, type: String, required: false
input :last_name, type: String
output :full_name, type: String
make :assign_full_name
private
def assign_full_name
outputs.full_name = [
inputs.first_name,
inputs.middle_name,
inputs.last_name
].compact.join(" ")
end
endヘルパー
ヘルパーallow_service_as_success!
.call!呼び出しを成功結果でモックします。
before do
allow_service_as_success!(UsersService::Accept)
endbefore do
allow_service_as_success!(UsersService::Accept) do
{
user: user
}
end
endヘルパーallow_service_as_success
.call呼び出しを成功結果でモックします。
before do
allow_service_as_success(UsersService::Accept)
endbefore do
allow_service_as_success(UsersService::Accept) do
{
user: user
}
end
endヘルパーallow_service_as_failure!
.call!呼び出しを失敗結果でモックします。
before do
allow_service_as_failure!(UsersService::Accept) do
ApplicationService::Exceptions::Failure.new(
message: "Some error"
)
end
endヘルパーallow_service_as_failure
.call呼び出しを失敗結果でモックします。
before do
allow_service_as_failure(UsersService::Accept) do
ApplicationService::Exceptions::Failure.new(
message: "Some error"
)
end
endオプション
オプションwith
メソッドallow_service_as_success!、allow_service_as_success、 allow_service_as_failure!、およびallow_service_as_failureはwithオプションをサポートします。
デフォルトでは、このオプションはサービス引数の受け渡しを必要とせず、 infoメソッドに基づいてデータを自動的に決定します。
before do
allow_service_as_success!(
UsersService::Accept,
with: { user: user }
)
endbefore do
allow_service_as_success!(
UsersService::Accept,
with: { user: user }
) do
{
user: user
}
end
endマッチャー
マッチャーhave_input have_service_input
type
inputの型を検証します。単一の値を対象とします。
it do
expect { perform }.to(
have_input(:id)
.type(Integer)
)
endtypes
inputの型を検証します。複数の値を対象とします。
it do
expect { perform }.to(
have_input(:ids)
.types(Integer, String)
)
endrequired
inputが必須であるかを検証します。
it do
expect { perform }.to(
have_input(:id)
.type(Integer)
.required
)
endoptional
inputが任意であるかを検証します。
it do
expect { perform }.to(
have_input(:middle_name)
.type(String)
.optional
)
enddefault
inputのデフォルト値を検証します。
it do
expect { perform }.to(
have_input(:middle_name)
.type(String)
.optional
.default("<unknown>")
)
endconsists_of
inputコレクションのネストされた型を検証します。複数の値を指定できます。
it do
expect { perform }.to(
have_input(:ids)
.type(Array)
.required
.consists_of(String)
)
endit do
expect { perform }.to(
have_input(:ids)
.type(Array)
.required
.consists_of(String)
.message("Input `ids` must be a collection of `String`")
)
endinclusion
inputのinclusionオプションの値を検証します。
it do
expect { perform }.to(
have_input(:event_name)
.type(String)
.required
.inclusion(%w[created rejected approved])
)
endit do
expect { perform }.to(
have_input(:event_name)
.type(String)
.required
.inclusion(%w[created rejected approved])
.message(be_a(Proc))
)
endschema input (^2.12.0) internal (^2.12.0) output (^2.12.0)
inputのschemaオプションの値を検証します。
it do
expect { perform }.to(
have_input(:payload)
.type(Hash)
.required
.schema(
{
request_id: { type: String, required: true },
user: {
# ...
}
}
)
)
endit do
expect { perform }.to(
have_input(:payload)
.type(Hash)
.required
.schema(
{
request_id: { type: String, required: true },
user: {
# ...
}
}
)
.message("Problem with the value in the schema")
)
endmessage input (^2.12.0) internal (^2.12.0) output (^2.12.0)
最後のチェーンのmessageを検証します。 現在はconsists_of、inclusion、schemaチェーンでのみ動作します。
it do
expect { perform }.to(
have_input(:ids)
.type(Array)
.required
.consists_of(String)
.message("Input `ids` must be a collection of `String`")
)
endmust
inputのmustに期待されるキーが存在するかを検証します。 複数の値を指定できます。
it do
expect { perform }.to(
have_input(:invoice_numbers)
.type(Array)
.consists_of(String)
.required
.must(:be_6_characters)
)
endvalid_with
このチェーンは渡されたデータに基づいてinputの実際の動作を検証します。
subject(:perform) { described_class.call!(**attributes) }
let(:attributes) do
{
first_name: first_name,
middle_name: middle_name,
last_name: last_name
}
end
it do
expect { perform }.to(
have_input(:first_name)
.valid_with(attributes)
.type(String)
.required
)
endマッチャーhave_internal have_service_internal
type
internal属性の型を検証します。単一の値を対象とします。
it do
expect { perform }.to(
have_internal(:id)
.type(Integer)
)
endtypes
internal属性の型を検証します。複数の値を対象とします。
it do
expect { perform }.to(
have_internal(:ids)
.types(Integer, String)
)
endconsists_of
internal属性コレクションのネストされた型を検証します。 複数の値を指定できます。
it do
expect { perform }.to(
have_internal(:ids)
.type(Array)
.consists_of(String)
)
endit do
expect { perform }.to(
have_internal(:ids)
.type(Array)
.consists_of(String)
.message("Input `ids` must be a collection of `String`")
)
endinclusion
internal属性のinclusionオプションの値を検証します。
it do
expect { perform }.to(
have_internal(:event_name)
.type(String)
.inclusion(%w[created rejected approved])
)
endit do
expect { perform }.to(
have_internal(:event_name)
.type(String)
.inclusion(%w[created rejected approved])
.message(be_a(Proc))
)
endschema input (^2.12.0) internal (^2.12.0) output (^2.12.0)
internal属性のschemaオプションの値を検証します。
it do
expect { perform }.to(
have_internal(:payload)
.type(Hash)
.schema(
{
request_id: { type: String, required: true },
user: {
# ...
}
}
)
)
endit do
expect { perform }.to(
have_internal(:payload)
.type(Hash)
.schema(
{
request_id: { type: String, required: true },
user: {
# ...
}
}
)
.message("Problem with the value in the schema")
)
endmessage input (^2.12.0) internal (^2.12.0) output (^2.12.0)
最後のチェーンのmessageを検証します。 現在はconsists_of、inclusion、schemaチェーンでのみ動作します。
it do
expect { perform }.to(
have_internal(:ids)
.type(Array)
.consists_of(String)
.message("Input `ids` must be a collection of `String`")
)
endmust
internal属性のmustに期待されるキーが存在するかを検証します。 複数の値を指定できます。
it do
expect { perform }.to(
have_internal(:invoice_numbers)
.type(Array)
.consists_of(String)
.must(:be_6_characters)
)
endマッチャーhave_output have_service_output
instance_of
output属性の型を検証します。
it do
expect(perform).to(
have_output(:event)
.instance_of(Event)
)
endcontains
INFO
リリース2.9.0でチェーンwithはcontainsに名前変更されました。
output属性の値を検証します。
it do
expect(perform).to(
have_output(:full_name)
.contains("John Fitzgerald Kennedy")
)
endnested
output属性のネストされた値を指し示します。
it do
expect(perform).to(
have_output(:event)
.nested(:id)
.contains("14fe213e-1b0a-4a68-bca9-ce082db0f2c6")
)
endマッチャーbe_success_service
it { expect(perform).to be_success_service }with_output
it do
expect(perform).to(
be_success_service
.with_output(:id, "...")
)
endwith_outputs
it do
expect(perform).to(
be_success_service
.with_outputs(
id: "...",
full_name: "...",
# ...
)
)
endマッチャーbe_failure_service
it { expect(perform).to be_failure_service }it "returns expected failure" do
expect(perform).to(
be_failure_service
.with(ApplicationService::Exceptions::Failure)
.type(:base)
.message("Some error")
.meta(nil)
)
endwith
it "returns expected failure" do
expect(perform).to(
be_failure_service
.with(ApplicationService::Exceptions::Failure)
)
endtype
it "returns expected failure" do
expect(perform).to(
be_failure_service
.type(:base)
)
endmessage
it "returns expected failure" do
expect(perform).to(
be_failure_service
.message("Some error")
)
endmeta
it "returns expected failure" do
expect(perform).to(
be_failure_service
.meta(nil)
)
end