From majestic-rails
Writes Minitest tests for Ruby and Rails apps using traditional/spec styles, fixtures, mocking, and integration patterns. Use when creating test files or testing features.
How this skill is triggered — by the user, by Claude, or both
Slash command
/majestic-rails:minitest-coderThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
- **AAA Pattern**: Arrange-Act-Assert structure for clarity
| Style | Best For | Syntax |
|---|---|---|
| Traditional | Simple unit tests | test "description" |
| Spec | Complex scenarios with contexts | describe/it with let/subject |
class UserTest < ActiveSupport::TestCase
test "validates presence of name" do
user = User.new
assert_not user.valid?
assert_includes user.errors[:name], "can't be blank"
end
end
class UserTest < ActiveSupport::TestCase
describe "#full_name" do
subject { user.full_name }
let(:user) { User.new(first_name: "Buffy", last_name:) }
describe "with last name" do
let(:last_name) { "Summers" }
it "returns full name" do
assert_equal "Buffy Summers", subject
end
end
end
end
test/models/ - Model unit teststest/services/ - Service object teststest/integration/ - Full-stack teststest/mailers/ - Mailer teststest/jobs/ - Background job teststest/fixtures/ - Test datatest/test_helper.rb - Configurationapp/models/user.rb → test/models/user_test.rbclass Users::ProfileServiceTestrequire 'test_helper' (auto-imported)See references/spec-patterns.md for detailed examples.
| Pattern | Use Case |
|---|---|
subject { ... } | Method under test |
let(:name) { ... } | Lazy-evaluated data |
describe "context" | Group related tests (max 3 levels) |
before { ... } | Complex setup |
describe "#process" do
subject { processor.process }
let(:processor) { OrderProcessor.new(order) }
let(:order) { orders(:paid_order) }
it "succeeds" do
assert subject.success?
end
end
# test/fixtures/users.yml
alice:
name: Alice Smith
email: [email protected]
created_at: <%= 2.days.ago %>
class UserTest < ActiveSupport::TestCase
fixtures :users
test "validates uniqueness" do
duplicate = User.new(email: users(:alice).email)
assert_not duplicate.valid?
end
end
See references/spec-patterns.md for detailed examples.
| Method | Purpose |
|---|---|
Object.stub :method, value | Stub return value |
Minitest::Mock.new | Verify method calls |
test "processes payment" do
PaymentGateway.stub :charge, true do
processor = OrderProcessor.new(order)
assert processor.process
end
end
# Boolean
assert user.valid?
assert_not user.admin?
# Equality
assert_equal "Alice", user.name
assert_nil user.deleted_at
# Collections
assert_includes users, admin_user
assert_empty order.items
# Exceptions
assert_raises ActiveRecord::RecordInvalid do
user.save!
end
# Changes
assert_changes -> { user.reload.status }, to: "active" do
user.activate!
end
assert_difference "User.count", 1 do
User.create(name: "Charlie")
end
# Responses
assert_response :success
assert_redirected_to user_path(user)
test "processes refund" do
# Arrange
order = orders(:completed_order)
original_balance = order.user.account_balance
# Act
result = order.process_refund
# Assert
assert result.success?
assert_equal "refunded", order.reload.status
end
Spec style with subject:
describe "#process_refund" do
subject { order.process_refund }
let(:order) { orders(:completed_order) }
it "updates status" do
subject
assert_equal "refunded", order.reload.status
end
it "credits user" do
assert_changes -> { order.user.reload.account_balance }, by: order.total do
subject
end
end
end
| Type | Test For |
|---|---|
| Models | Validations, associations, scopes, callbacks, methods |
| Services | Happy path, sad path, edge cases, external integrations |
| Controllers | Status codes, redirects, parameter handling |
| Jobs | Execution, retry logic, error handling |
class UserTest < ActiveSupport::TestCase
# Validations
test "validates presence of name" do
user = User.new(email: "[email protected]")
assert_not user.valid?
assert_includes user.errors[:name], "can't be blank"
end
# Methods
describe "#full_name" do
subject { user.full_name }
let(:user) { User.new(first_name: "Alice", last_name: "Smith") }
it "returns full name" do
assert_equal "Alice Smith", subject
end
describe "without last name" do
let(:user) { User.new(first_name: "Alice") }
it "returns first name only" do
assert_equal "Alice", subject
end
end
end
end
See references/advanced-patterns.md for production-tested patterns from 37signals.
| Pattern | Problem Solved |
|---|---|
| Current.account fixtures | Multi-tenant URL isolation |
| Assertion-validating helpers | Early failure with clear messages |
| Deterministic UUIDs | Predictable fixture ordering |
| VCR timestamp filtering | Reusable API cassettes |
| Thread-based concurrency | Race condition detection |
| Adapter-aware helpers | SQLite/MySQL compatibility |
See references/anti-patterns.md for detailed examples.
| Anti-Pattern | Why Bad |
|---|---|
require 'test_helper' | Auto-imported |
| >3 nesting levels | Unreadable output |
@ivars instead of let | State leakage |
Missing subject | Repetitive code |
assert x.include?(y) | Use assert_includes |
| Testing private methods | Implementation coupling |
| Not using fixtures | Slow tests |
Organization:
require 'test_helper'Style Choice:
Test Data:
let for shared datasubject for method under testAssertions:
assert_changes, assert_difference)Coverage:
Traditional: Simple validations, straightforward tests, no shared setup
Spec: Multiple contexts, lazy evaluation needed, nested scenarios, reusable subject
Can mix both in the same file if it improves clarity.
npx claudepluginhub majesticlabs-dev/majestic-marketplace --plugin majestic-railsWrites RSpec tests for Ruby and Rails apps using AAA pattern, describe/context blocks, subject/let, fixtures, allow/expect mocking, and shoulda matchers. Use for spec files, test cases, or new features.
Enforces TDD with Minitest for Rails: fixtures, model/controller tests, WebMock HTTP mocking, integration tests; rejects RSpec/system tests.
Assists writing, reviewing, and improving RSpec tests for Ruby on Rails apps including model, controller, system, and integration specs using Better Specs and thoughtbot best practices.