agentleFS
G1JoshiG1Joshi/Agent-Skills/skills/testing/rspec/SKILL.md

rspec

Skill15 starsChanged 42 days agoMITView on GitHub

Expert RSpec testing assistance covering Ruby BDD testing, mocks, expectations, and let/subject helpers. Use when writing Rails/Ruby tests, testing controllers/models, or running `bundle exec rspec`.

5 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

7 rules. 0 are common, 1 is distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use nested context blocks with lazy-evaluated let:

    line 104
  2. Very specific:

    Use instance_double Instead of double: Catch renamed or deleted methods immediately during test execution.

    line 134
  3. Very specific:

    Use build_stubbed in FactoryBot for Unit Tests: Avoid touching the database when testing pure model logic.

    line 135
  4. Very specific:

    Keep it Blocks to a Single Expectation: Isolate failures clearly.

    line 136
  5. Very specific:

    Use context Blocks Starting with "when" or "with": Clarify environmental preconditions and business states.

    line 137
  6. Distinctive:

    Test framework features: Test custom business logic.

    line 142
  7. Very specific:

    Leave mysterious instance variables (@user): Use explicit let bindings for predictable memoization.

    line 143

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

RSpec

RSpec is the primary testing tool for Ruby (especially Rails). It focuses on "Behavior Driven Development" (BDD), making tests read like documentation specifications.

When to Use

  • Ruby on Rails BDD Testing: The standard Behavior-Driven Development testing framework for Ruby and Rails applications.
  • Expressive Specification Design: Writing readable, self-documenting specifications using describe, context, and it.
  • Database & Model Validation: Testing ActiveRecord validations, scopes, and associations with shoulda-matchers.
  • Comprehensive Mocking & Stubbing: Isolating dependencies using instance_double and allow().to receive().

Quick Start

# user_spec.rb
RSpec.describe User, type: :model do
  context "when newly created" do
    it "has no name" do
      user = User.new
      expect(user.name).to be_nil
    end
  end
end

Core Concepts

Hierarchical Contexts & Readable Specifications

Structures tests to match human-readable business expectations:

# spec/models/order_spec.rb
RSpec.describe Order, type: :model do
  describe "#apply_coupon" do
    context "when coupon is valid" do
      let(:coupon) { create(:coupon, discount_percentage: 20) }
      let(:order) { create(:order, total: 100) }

      it "deducts percentage from order total" do
        order.apply_coupon(coupon)
        expect(order.total).to eq(80)
      end
    end

    context "when coupon has expired" do
      let(:expired_coupon) { create(:coupon, expires_at: 1.day.ago) }
      let(:order) { create(:order, total: 100) }

      it "raises an expired coupon error" do
        expect { order.apply_coupon(expired_coupon) }
          .to raise_error(CouponExpiredError)
      end
    end
  end
end

Verified Mocks (instance_double)

Prevents stale mocks by validating that mocked methods actually exist on the target class:

it "calls external payment gateway" do
  gateway = instance_double(PaymentGateway)
  expect(gateway).to receive(:charge).with(100).and_return(true)

  service = CheckoutService.new(gateway: gateway)
  service.process(100)
end

FactoryBot Integration for Test Fixtures

Generates flexible model test records without brittle fixtures:

# spec/factories/users.rb
FactoryBot.define do
  factory :user do
    sequence(:email) { |n| "user#{n}@example.com" }
    password { "Password123!" }
    role { "member" }

    trait :admin do
      role { "admin" }
    end
  end
end

Common Patterns

Expressive Contexts with Let and Subject

Problem: Monolithic test cases testing both valid and invalid states together with hard-to-read assertions.

Solution: Use nested context blocks with lazy-evaluated let:

RSpec.describe Order do
  let(:order) { described_class.new(amount: amount) }

  context "when amount is positive" do
    let(:amount) { 50 }

    it "is valid and processes successfully" do
      expect(order).to be_valid
      expect(order.process).to be true
    end
  end

  context "when amount is zero or negative" do
    let(:amount) { 0 }

    it "is invalid with an error message" do
      expect(order).not_to be_valid
      expect(order.errors[:amount]).to include("must be greater than 0")
    end
  end
end

Best Practices

Do:

  • Use instance_double Instead of double: Catch renamed or deleted methods immediately during test execution.
  • Use build_stubbed in FactoryBot for Unit Tests: Avoid touching the database when testing pure model logic.
  • Keep it Blocks to a Single Expectation: Isolate failures clearly; one assertion per specification.
  • Use context Blocks Starting with "when" or "with": Clarify environmental preconditions and business states.

Don't:

  • Overuse let! (bang): Eager loading on every test slows down test suites; prefer lazy let unless eager creation is required.
  • Test framework features: Test custom business logic; avoid testing standard Rails ActiveRecord functionality directly.
  • Leave mysterious instance variables (@user): Use explicit let bindings for predictable memoization.

Troubleshooting

ErrorCauseSolution
LoadError: cannot load such file -- rails_helperRunning RSpec in a Rails app without loading helper.Ensure require 'rails_helper' is at the top of the spec file.
Double received unexpected messageTest double received a method call that was not declared.Allow or expect method with allow(mock).to receive(:method_name).
RSpec::Expectations::ExpectationNotMetErrorExpected return value or predicate failed.Check diff in terminal output and verify matcher syntax.

References

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.