12/08/2018, 14:11

Giới Thiệu Rspec phần 2

Testing class method và scope By giờ chugns ta test khả năng của model User với việc nó sẽ trả về danh sách các User với được bắt đầu với các kí tự dược đưa vào. Giả sư chúng ta nhập vào chữ T thì kết quả nhận được sẽ bao gồm "Tho Bay Mau", "Tieu Ho", nhưng "Bao Hong" sẽ không xuất hiện trong ...

Testing class method và scope

By giờ chugns ta test khả năng của model User với việc nó sẽ trả về danh sách các User với được bắt đầu với các kí tự dược đưa vào. Giả sư chúng ta nhập vào chữ T thì kết quả nhận được sẽ bao gồm "Tho Bay Mau", "Tieu Ho", nhưng "Bao Hong" sẽ không xuất hiện trong danh sách kết quả của chúng ta.

Trước hết ta viết một class method cho model User nhằm lấy ra các user được bắt đầu bởi các kí tự cho trước.

Trong model User

class << self
  def by_letter letter
    where("name LIKE ?", "#{letter}%").order(:name)
  end
end

Tiếp theo, ta sẽ thêm test case vào file spec của model User

describe User do
  it "return a sorted array of result that match" do
    tho = User.create(
      name: "Tho bay mau",
      email: "thobaymau@email.com"
    )
    bao = User.create(
      name: "Bao hong",
      email: "baohong@email.com"
    )
    tieu_ho = User.create(
      name: "Tieu Ho",
      email: "tieuho@email.com"
    )
    expect(User.by_letter("T"))))).to eq [tho, tieu_ho]
  end
end

Tiếp theo chúng ta thực hiện lệnh bundle exec rspec để thi hành các test case phía trên.

Test for failur

Chúng ta vừa thực hiện việc kiểm thử cho method by_letter của class User, nhưng chúng ta mới thực hiện một phần của test case ban đầu, đó là kiểm tra output khi input đúng với những gì ta mong đợi. Nhưng chuyện gì sẽ xảy ra khi ta nhập vào input là các kí tự không đúng những gì ta mong đợi?

ta tiếp tục viets thêm vào file spec của model User

describe User do
  it "return a sorted array of result that match" do
    tho = User.create(
      name: "Tho bay mau",
      email: "thobaymau@email.com"
    )
    bao = User.create(
      name: "Bao hong",
      email: "baohong@email.com"
    )
    tieu_ho = User.create(
      name: "Tieu Ho",
      email: "tieuho@email.com"
    )
    expect(User.by_letter("T"))))).not_to include bao
  end
end

Như vậy ta đã kiểm tra khi nhập vào kí tự "T" thì kết quả trả về sẽ không bao gồm các User với name không được bắt đầu bởi kí tự "T", ở đu là User với name là "Bao hong" sẽ không nằm trong danh sách các kết quả trả về mà ta mong đợi. bạn nên thực hiện lệnh "bundle exec rspec" để thi hành test case và xem kết quả trà về từ test case trên.

DRYer specs với describe, context, before và after

Trước hết DRY là gì, DRY ở đy là viết tắt của cụm từ "Dont Repeat Yourself", có nghĩa là không lặp lại những gì mình đã viết. Đy là việc khá thông dụng trong giứi lập trình và đặc bietsj là các Rubyist.

Xuyên suốt các test case từ bài trước đến giờ để tạo dữ liệu mẫu nhàm phục vụ cho quá trình test, chúng ta đã lặp lại việc tạo User với cùng một user name, email, khá nhiều lần. Việc này khiến code của chúng ta trở nên dài dòng, và thiếu sự trong sáng, đồng thời cũng tiêu tốn nhiều thời gian cho việc viết đi viết lại nhưng đoạn code cũ.

Vậy ta cần làm gì đẻ tránh việc làm trên?

Bắt tay vào việc refractor lại code rspec phía trên.

Ta sẽ sửa lại chúng như sau:

describe User do
  before :each do
    @tho = User.creaet(
      name: "Tho bay mau",
      email: "thobaymau@email.com"
    )

    @bao = User.create(
      name: "Bao Hong",
      email: "baohong@email.com"
    )
  end

    @tieu_ho = User.creaet(
      name: "Tieu Ho",
      email: "tieuho@email.com"
    )

    describe "filter name by letter" do
    context "matching letters" do
    end

    context "non matching letters" do
    end
  end
end

Như vậy chúng ta đã giảm thiểu độ dài của code bằng cách gộp các đoạn khởi tạo giống nhau lại cùng nhau, và gộp các test case dành cho việc kiểm thử class method by_letter lại với nhau.

0