Skip to content

Instantly share code, notes, and snippets.

@steveclarke
Created May 15, 2025 04:34
Show Gist options
  • Save steveclarke/9e9f12018ca2ae1219d6618df8d8775d to your computer and use it in GitHub Desktop.
Save steveclarke/9e9f12018ca2ae1219d6618df8d8775d to your computer and use it in GitHub Desktop.
rspec Cursor Rules
---
description:
globs: spec/**/*
alwaysApply: false
---
# RSpec Testing Guidelines
## Core Principles
- Use RSpec for all tests
- Use FactoryBot for test data
- Use Shoulda Matchers for concise, readable tests
- Don't test private methods
- Prefer request specs over controller specs
## Request Specs
- Test full HTTP request/response cycle
- Include authentication contexts where needed:
```ruby
include_context "with authenticated user"
include_context "with admin user"
```
- Test both success and failure cases
- Verify response status and content
- Organize request specs into multiple files:
- Create one file per endpoint (e.g., `get_products_spec.rb`, `update_product_spec.rb`)for
## Shared Contexts
Use these for authentication:
- [users_shared_context.rb](mdc:spec/support/shared_contexts/users_shared_context.rb)
- [admin_user_shared_context.rb](mdc:spec/support/shared_contexts/admin_user_shared_context.rb)
## Shoulda Matchers
Use Shoulda Matchers for concise, readable validation and association tests:
### Model Tests
```ruby
RSpec.describe Product, type: :model do
# Validations
it { should validate_presence_of(:name) }
it { should validate_numericality_of(:price).is_greater_than(0) }
# Associations
it { should belong_to(:category) }
it { should have_many(:reviews) }
end
```
### Controller Tests
```ruby
RSpec.describe ProductsController, type: :controller do
describe "GET #index" do
it { should respond_with(:ok) }
it { should render_template(:index) }
end
describe "POST #create" do
it { should permit(:name, :price, :description).for(:create) }
end
end
```
## Example
```ruby
RSpec.describe "Products API", type: :request do
include_context "with authenticated user"
describe "GET /api/products" do
it "returns products list" do
create_list(:product, 3)
get "/api/products"
expect(response).to have_http_status(:ok)
expect(json_response[:products]).to be_present
end
end
end
```
## Best Practices
- One expectation per test when possible
- Use descriptive context and example names
- Keep tests focused and isolated
- Use appropriate matchers
- Clean up test data after each example
- Use Shoulda Matchers for validation and association tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment