Bắt đầu học Rspec test trên Model
Mở đầu Rspec test trong Ruby on Rails sẽ được thực hiện trên ba thành phần sau: Model View Controller Khi mới tìm hiểu RSpec là gì và viết những dòng RSpec đầu tiên thì cách đơn giản nhất là bắt đầu với "Model". Những thứ cần chuẩn bị Project của chúng ta cần phải có Gemfile như ...
Mở đầu
Rspec test trong Ruby on Rails sẽ được thực hiện trên ba thành phần sau:
- Model
- View
- Controller
Khi mới tìm hiểu RSpec là gì và viết những dòng RSpec đầu tiên thì cách đơn giản nhất là bắt đầu với "Model".
Những thứ cần chuẩn bị
Project của chúng ta cần phải có Gemfile như sau:
- Gemfile
group :development, :test do gem 'rspec-rails' gem 'factory_girl_rails' end group :test do gem 'faker' gem 'capybara' gem 'guard-rspec' gem 'launchy' gem "shoulda-matchers", github: "thoughtbot/shoulda-matchers" end
Sau khi chắc chắn các Gemfile của mình có những 'gem' như trên thì ta chạy dòng lệnh sau:
bundle install
- Model trong Project:
Trong bài viết này giả sử chúng ta có 2 model là User và Booking. Mối quan hệ giữa User và Booking là 1-n ( Tức là một User có thể đặt nhiều lần Booking và mỗi Booking chỉ được tạo bởi một User).
- Đối với model User:
/* app/models/user.rb */ class User < ApplicationRecord has_many :bookings end
- Đối với model Booking:
/* app/models/booking.rb */ class Booking < ApplicationRecord belongs_to :users validates :booking_from, presence: true end
Bắt đầu viết RSpec cho Model
- Tạo nơi lưu trữ RSpec code:
Để bắt đầu viết RSpec cho model thì đầu tiên phải tạo thư mục 'spec' trong Project.
- Thư mục 'spec' là nơi chứa các dòng lệnh RSpec của chúng ta.
Nếu vẫn chưa có thư mục 'spec' thì bạn gõ các dòng lệnh sau:
framgia@abc$ cd your_application framgia@abc/your_application$ mkdir spec
- Tạo code RSpec cho từng Model:
Như đã mô tả ở trên, chúng ta có 2 Model là User và Booking nên sẽ tạo tương ứng 2 tệp tin là 'user_spec.rb' và 'booking_spec.rb' để tiến hành test lần lượt cho 2 model này.
Khi viết Test cho một Model nào đó, ta chỉ cần Test cho 2 vấn đề sau là đủ:
- Mối quan hệ với các Model khác.
- Validate dữ liệu.
Do đó đối với mỗi Model ta cần tạo ra bộ khung cho nó bằng cách sử dụng từ khóa 'context' như sau:
/* app/spec/models/user_spec.rb */ require "rails_helper" RSpec.describe User, type: :model do context "associations" do # We will type something later end context "validates" do # We will type something later end end
Tương tự với model User thì model Booking như sau:
/* app/spec/models/booking_spec.rb */ require "rails_helper" RSpec.describe Booking, type: :model do context "associations" do # We will type something later end context "validates" do # We will type something later end end
Rspec cho User
Chúng ta đang viết Rspec test cho Model User, do đó cần phải mở thư mục RSpec của model này: 'app/spec/models/user_spec.rb'
Sau khi đã mở thư mục trên thì ta tiến hành từng bước như sau:
- Mối quan hệ với các Model khác:
"Một User có 'NHIỀU' Booking" => "User has_many Bookings"
Do đó:
/* app/spec/models/user_spec.rb */ require "rails_helper" RSpec.describe User, type: :model do context "associations" do it {is_expected.to has_many :bookings} end context "validates" do # We will type something later end end
Dòng chúng ta vừa thêm vào là
it {is_expected.to has_many :bookings}
Chúng ta sẽ phân tích từng thành phần nhỏ:
- it: Mô tả một ví dụ, nội dung của ví dụ sẽ nằm trong cặp dấu ngoặc {} theo sau nó.
- is_expected.to: cú pháp của 'gem shoulda-matchers' mà chúng ta đã cài ở trên.
- has_many :bookings : Diễn đạt mối quan hệ ta cần Test.
- Validate dữ liệu
Do ở trên User của chúng ta không có validates gì nên phần validates này sẽ được đề cập đến ở model Booking.
Rspec cho Booking
Tương tự, chúng ta đang viết Rspec test cho Model Booking, do đó cần phải mở thư mục RSpec của model này: 'app/spec/models/booking_spec.rb'
Sau khi đã mở thư mục trên thì ta tiến hành từng bước như sau:
- Mối quan hệ với các Model khác:
"Một Booking tạo bởi duy nhất một User" => "Một booking phụ thuộc vào một User" => "Booking belongs_to User"
Do đó:
/* app/spec/models/booking_spec.rb */ require "rails_helper" RSpec.describe Booking, type: :model do context "associations" do it {is_expected.to belong_to :user} end context "validates" do # We will type something later end end
Dòng chúng ta vừa thêm vào là
it {is_expected.to belong_to :user}
Chúng ta sẽ phân tích từng thành phần nhỏ:
- it và is_expected.to: Đã giải thích ở trên.
- belong_to :user : Diễn đạt mối quan hệ ta cần Test.
- Validate dữ liệu
Ở phần model ta đã validates dữ liệu của Booking như sau:
validates :booking_from, presence: true
Do đó, ở phần context 'validates' ta có:
/* app/spec/models/booking_spec.rb */ require "rails_helper" RSpec.describe Booking, type: :model do context "associations" do it {is_expected.to belong_to :user} end context "validates" do it {is_expected.to validate_presence_of :booking_from} end end
Dòng chúng ta vừa thêm vào là
it {is_expected.to validate_presence_of :booking_from}
Chúng ta sẽ phân tích từng thành phần nhỏ:
- it và is_expected.to: Đã giải thích ở trên.
- validate_presence_of :booking_from : Cần trường booking_from phải không được nil.
Tổng kết
Vậy chúng ta đã đi qua sơ lược về Test Model trong RSpec, ở phần sau chúng ta sẽ tiếp tục với RSpec Test trong Controller.
Bài viết này được tham khảo từ tài liệu sau:
https://everydayrails.com/2012/03/19/testing-series-rspec-models-factory-girl.html
https://github.com/thoughtbot/shoulda-matchers