Please follow this guideline to refine your rspec, make sure code is better after you modify anything
RSpec.describe Api::UsersController, type: :controller do
...
end
there are also some other types
- Model: type: :model
- Controller: type: :controller
- Request: type: :request
- Feature: type: :feature
- View: type: :view
- Helper: type: :helper
- Mailer: type: :mailer
- Routing: type: :routing
if you want to verify render results, like json or HTML returned by controller, you need call render_views
methods at very beginning of your test.
RSpec.describe Api::UsersController, type: :controller do
render_views
end
It will be more clear if you can use HTTP method and URL to describe action test instead of action name
# recommend
describe 'get /api/users/:user_id' do
...
end
# not recommand
describe '#get' do
...
end
let
is a method to help us prepare test data, it will create data unless you call it.
# recommend
it 'create user' do
user
end
let(:user) {...}
# not recommend
it 'create user' do
@user
end
before { @user = User.create }
In controller test, it is important to know who is current_user
. Please make sure current_user
is the right people with right permission for a specific test.
it 'get users' do
allow(controller).to receive(:current_user).and_return(student)
end
let(:student)
It's easier to parse json to symbol key hash when you verify json in test.
# {name: 'Harry Potter'}, recommend
JSON.parse(response.body, symbolize_names: true)
# or call json_resonse method in model_helper.rb, recommend
let(:json) { json_response(response) }
# {'name' => 'Harry Potter'}, not recommend
JSON.parse(response.body)
HTTP code and response keys are very important for a response, we should always make sure they are verified. If there are more test in same action test, you don't need verify http code and json keys every time, however you need to make sure http code and json keys are verified once.
describe 'get /api/users' do
it 'get all admin' do
...
expect(response).to have_http_status(:ok)
expect(json).to match(name: 'harry', gender: 'female')
end
it 'get all students' do
end
end
let(json) {...}
It will make test code more readable if split test into: prepare data, do some action, and verify.
# add new line to split
it 'reset password' do
user = User.create
user.reset_password
expect(user.password).to eq('old_password')
end
#or you can follow this way
it 'reset password' do
user.reset_password
expect(user.password).to eq('old_password')
end
let(:user) { User.create }
before
and let
is some step to prepare data, we should always focus test code at first glance.
Rspec.describe 'UsersController' do
describe 'get /api/users' do
...
end
describe 'put /api/users/:id' do
...
end
before { ... }
let(:user) { ... }
end
match
is much powerful and flexible for verify, it can return more accurate error message when something went wrong. You can read this for detail
# recommend
it 'user list' do
...
expect(json).to match([
a_hash_including(name: 'Harry'),
a_hash_including(name: 'Snape'),
])
end
#not recommend
it 'user list' do
...
expect(json.length).to eq(2)
expect(json[0]).to include(name: 'Harry')
expect(json[1]).to include(name: 'Snape')
end
#other
We can use these helper method to make our code more readable.
# will return 404 if not found
found?(@user = User.find(params[:id])) do
render :index, status: :ok
end
# verify model object only, return 400 and error message if invalid
valid?(@user) { render :index, status: :ok }
# verify value is truthy, return 400 with customized error message if false
truthy?(@user.update(params), 'error message') do
render :index, status: :ok
end
Personally I don't recommend copy-paste
code, if you really want to do that, please pay attention to following things.
- try to refactor the code you want to copy, maybe you don't need copy after refactor
- read paste code line by line to make sure that is exactly what you want.
- slap your face if you create bug because you just copy and paste but didn't read it
Please make sure you clean the house before you leave, make code better and cleaner after you modify it.
Models like Rubric and Template are very important in our system, please do add more validation if you modify atrribute of that model
If you may need look all specs in our system
- Modify model attribute
- Modify model validator
Remember, if you think prepare meaningful fake data is hard, our qa have to test harder after you finish development, do not leave your shit to other team members!!!
- controller test, verify http status code, response result and model created/deleted/changed
- model test, verify atributed changed