Tìm hiểu gem shoulda matchers trong viết Rspec
Bài đăng này đã không được cập nhật trong 8 năm
1.Giới thiệu
Viết sử dụng Rspec
để viết test cho các dự án Rails là hết sức quan trọng. Đối với những dự án lớn thì việc viết test sẽ vô cùng phức tạp và mất thời gian.Shoulda Matchers
cung cấp cách viết 1 dòng lệnh Rspec
dùng để test các chức năng của Rails
. Nó giúp bạn viết test 1 cách ngắn gọn, rõ ràng và ít gặp lỗi hơn. Sử dụng Shoulda Matchers
giúp cho việc viết rspec đơn giản, ngắn gọn và thú vị hơn.
Bài viết sẽ cho bạn 1 cái nhìn để so sánh giữ việc viết test dùng Should Matchers
với viết Rspec thông thường.
2.Cài đặt
Thêm vào Gemfile
group :test, :development do
gem 'rspec-rails'
gem 'shoulda-matchers'
end
Sau đó chạy bundle
3.Hướng dẫn sử dụng
Shoulda Matchers
cùng cấp cho ta rất nhiều phương thức dùng để test ví dụ:
ActiveModel
:
- have_secure_password
- validate_absence_of
- validate_acceptance_of
- validate_confirmation_of
- validate_exclusion_of
- validate_inclusion_of
- validate_length_of
- validate_numericality_of
- validate_presence_of
Ví dụ : Below is an RSpec unit test for an ActiveModel. Each named test goes through four distinct phases: setup, exercise, verify, and teardown. The first named test ensures that you can't create a valid Contact record without a first_name attribute; the second test makes sure each Contact record has a unique email address, and the third enforces a minimum password length requirement.
Dưới đây là ví dụ viết RSpec cho một ActiveModel. Ví dụ yêu cầu khi tạo 1 Contact
:
- Phải có
first_name
. email
không được trùng lặp.password
phải có ít nhất 10 ký tự
describe Contact do
it "is invalid without a firstname" do
contact = Contact.create(first_name: nil, email: "ted@example.com", password: "empirestatebuilding")
contact.valid?
expect(contact.errors[:firstname]).to include("can't be blank")
end
it "is invalid with a duplicate email address" do
Contact.create(first_name: "Ted", email: "ted@example.com", password: "empirestatebuilding")
contact = Contact.new(first_name: "Robin", email: "ted@example.com", password: "montrealcanadiens")
contact.valid?
expect(contact.errors[:emal]).to include("has already been taken")
end
it "is invalid without a minimum password length" do
contact_one = Contact.create(first_name: "Ted", email: "ted@example.com", password: "empire")
contact_one.valid?
expect(Contact.errors[:password]).to include("password is too short")
end
end
Như bạn thấy ở trên, với cú pháp bình thường bạn phải mất rất nhiều dòng code để có thể kiểm tra được 3 logic ở trên. Nhưng với Shoulda Matchers
bạn chỉ cần phải dùng 3 dòng
describe Contact do
it { is_expected.to validate_presence_of(:firstname) }
it { is_expected.to validate_uniqueness_of(:email) }
it { is_expected.to validate_length_of(:password).is_at_least(10) }
end
ActiveRecord
:
- accept_nested_attributes_for
- belong_to
- define_enum_for
- have_and_belong_to_many
- have_db_column
- have_db_index tests
- have_many
- have_one
- have_readonly_attribute
- serialize
- validate_uniqueness_of
Một ví dụ về test mối quan hệ has_many
:
Cú pháp Rspec
:
describe Contact do
it "can have many phone numbers" do
contact = Contact.reflect_on_association(:phones)
expect(contact.macro).to eql(:has_many)
end
end
Cú pháp Rspec
+ Shoulda Matchers
:
describe Contact do
it { is_expected.to have_many(:phones).dependent(:destroy) }
end
ActionController
:
Controller
thường ít khi được viết test nhưng Shoulda Mathcher
cũng cung cấp rất đầy đủ các phương thức để ta có thể viết test 1 cách dễ dàng và ngắn gọn nhất.
- filter_param
- permit tests
- redirect_to
- render_template
- render_with_layout
- rescue_from tests
- respond_with tests
- route
- set_session
- set_flash
- use_after_action
- use_around_action
- use_before_action tests
Khi viết test cho 1 controller ta thường quan tâm tới :
- Trạng thái trả về của phương thức
- Controller có render template mong muốn không?
- Controller có render layout mong muốn không?
- Controller có tạo flash messages hay không?
- Thông tin có thay đổi hay bị xóa bỏ hay không?
- Controller có chuyển đến url mới không? Ví dụ :
describe ContactsController do
describe "GET #index" do
context "when user is logged in" do
with :user
before do
sign_in user
get :index
end
it { is_expected.to respond_with :ok }
it { is_expected.to render_with_layout :application }
it { is_expected.to render_template :index }
end
context "when user is logged out" do
before do
get :index
end
it { is_expected.to redirect_to new_session_path }
it { is_expected.to set_the_flash(:warning).to("Please log in.") }
it { is_expected.to set_session(:return_to).to(contacts_path) }
end
end
end
4.Kết luận
Thông qua các ví dụ trên ta có thể dễ dàng nhận thấy được sự đơn giản, tiện lợi trong việc sử dụng Shoulda mathcher
trong việc viết Rspec so với cú pháp thông thường.
Bạn có thể tìm hiểu nhiều ví dụ của Shoulda mathchers
và thông qua đó thực hành, áp dụng vào project của bạn tại :
https://github.com/thoughtbot/shoulda-matchers
Chúc các bạn thành công !!!
All rights reserved