Created
May 15, 2025 04:34
-
-
Save steveclarke/9e9f12018ca2ae1219d6618df8d8775d to your computer and use it in GitHub Desktop.
rspec Cursor Rules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
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