write-request-spec
Use this skill when writing RSpec request specs for Hanami 2.x Actions.
Workflow
Step 1 — Create the spec file
Place it under spec/requests/:
# spec/requests/users_spec.rb
RSpec.describe "Users", type: :request do
it "returns user JSON" do
get "/users/1"
expect(last_response).to be_successful
expect(json_body).to include(:id, :email, :name)
expect(json_body[:id]).to eq(1)
expect(json_body[:email]).to be_a(String)
end
end
Step 2 — Verify the spec fails
bundle exec rspec spec/requests/users_spec.rb
Confirm it fails because the route or action is unimplemented. Use the create-action skill to implement the corresponding Hanami endpoint and route before proceeding.
Step 3 — Verify specs pass
bundle exec rspec spec/requests/users_spec.rb
Core Rules
Send JSON request bodies — serialize parameters with
.to_jsonand setCONTENT_TYPEheader explicitly:it "creates a user" do post "/users", { user: { email: "alice@example.com", first_name: "Alice" } }.to_json, { "CONTENT_TYPE" => "application/json" } expect(last_response.status).to eq(201) expect(json_body[:id]).not_to be_nil endTest error responses — cover both 404 (not found) and 422 (validation errors) states:
it "returns 404 for missing user" do get "/users/99999" expect(last_response.status).to eq(404) expect(json_body[:error]).to eq("User not found") endIsolate database state — wrap specs that touch the database in a shared transaction context defined in
spec/support/database_cleaner.rb:# spec/support/database_cleaner.rb RSpec.shared_context "db transaction" do around do |example| Hanami.app["db.rom"] do |rom| rom.gateways[:default].transaction do |t| example.run t.rollback end end end endInclude in specs with:
include_context "db transaction"
Integration
| Related Skill | When to chain |
|---|---|
| create-action | Action definition precedes request spec implementation. |
| validate-params | Test validation contract parameters (422 responses). |
| create-repository | Database interactions are verified using real repositories. |