Tìm hiểu cơ bản về Rspec helper methods

Tram Ho

Helper methods

Trong khi sử dụng RSPEC, chắc hẳn các bạn sử dụng rất nhiều letlet!. Nhiều khi bạn sử dụng let hoặc let! rspec đều chạy đúng, có khi lại phải dùng let! mới được mà khi thì nên dùng let để tốt hơn cho hiệu suất.

Bạn đã hiểu rõ về let và let! chưa? Nếu câu trả lời là chưa thì đây là một tài liệu tham khảo cho bạn, còn ngược lại hãy để lại quan điểm của bạn về let và let! nhé.

let và let! là cái chi chi

Sử dụng let để định nghĩa một memoized helper method (giá trị của method được ghi nhớ). Giá trị trả về của memoized helper method sẽ được cached lại giữa những lần sử dụng nó trong cùng một example nhưng điều này không khả dụng giữa các example khác nhau.

Chú ý: let là lazy-evaluated có nghĩa là nó sẽ không được đánh giá cho đến khi method nó định nghĩa được gọi lần đầu tiên.

Bởi mặc định, let là threadsafe (luồng an toàn), nhưng bạn có thể thiết lập điều này thông qua config.threadsafe, điều này sẽ giúp hiệu suất của let nhanh hơn một chút.

let! giống với let ngoại trừ việc block của let! sẽ được thực thi trong một before hook ẩn. Điều đó đồng nghĩa với việc let! sẽ được thực thi trước mỗi example trong một group example khai báo nó.

Sự khác nhau giữa let và biến instance

Có 2 cách tiếp cập như sau: để định nghĩa ra một biến để sử dụng
Với let:

Với before và instance variable:

Điểm khác biệt:
Với instance variable trong before hook có thể bị mất từ một file này tới file khác. Với instance variable có thể nil nên dẫn đến nhiều lỗi tiềm ẩn.

Chứng minh let tạo ra một method

Đoạn code dưới đây tạo ra một method my_name và giá trị trả về của nó được cached.

Kết quả:

Giá trị trả về của method được tạo bằng let sẽ được cached

Đoạn code dưới đây gọi 2 lần method my_name nhưng chỉ in ra “thinking about what my name is…” một lần và kết quả trả về của my_name được in 2 lần. Tại sao?

Kết quả:

Đoạn code sau đây cho ta thấy method my_name được thực thi 1 lần và giá trị trả về của method đó sẽ được cached. Cho dù chúng ta gọi method my_name n lần thì kết quả cũng sẽ được lấy từ lần đầu tiên chứ không thực hiện n lần method my_name.

let là lazy evaluation và let! thì không

let
Khi nào method do let định nghĩa được gọi thì nó mới thực thi.
Code chứng minh:

Kết quả:

Từ kết quả in ra dễ dàng thấy rằng đến dòng code puts message thì message mới được thực hiện.

let!
Đúng theo định nghĩa, let! giống với let ngoại trừ việc block của let! sẽ được thực thi trong một before hook ẩn. Điều đó đồng nghĩa với việc let! sẽ được thực thi trước mỗi example trong một group example khai báo nó.

Code chứng minh:

Kết quả:

Nhận xét:
Kết quả của đoạn code cho thấy “let! block is running” được in ra đầu tiên đồng nghĩa let! được thực thi trước mỗi example trong example group khai báo nó.

Vì let! được chạy trước mỗi example nên bạn cần chú ý đến vị trí khai báo let! để tránh việc nó chạy trước những example không cần thiết. Trong những file rspec siêu bự thì nó sẽ gây ra hiệu suất rất tồi đó.

Theo quan điểm cá nhân thì khi các bạn nên dùng let! để tạo ra một method có xử lý tạo mới một record. Vì khi đó chúng ta có thể biết rõ ràng và chắc chắn record đó được tạo ra trước khi sử dụng record đó trong example nào đó.

Kết luận

Qua bài viết muốn làm rõ khái niệm và cách let và let! hoạt động, cũng như những sự khác biệt giữa chúng. Để chúng ta có thể viết Rspec không chỉ cho nó chạy đúng mà còn có hiệu suất cao nhất.

Bài viết tham khảo:

  1. https://www.codewithjason.com/difference-let-let-instance-variables-rspec/
  2. https://relishapp.com/rspec/rspec-core/v/3-10/docs/helper-methods/let-and-let
Chia sẻ bài viết ngay

Nguồn bài viết : Viblo