Mọi người dường như đã giải thích một số cách cơ bản mà chúng khác nhau, nhưng lại bỏ qua before(:all)
và không giải thích chính xác tại sao chúng nên được sử dụng.
Tôi tin rằng các biến cá thể không có chỗ được sử dụng trong phần lớn các thông số kỹ thuật, một phần do những lý do được đề cập trong câu trả lời này , vì vậy tôi sẽ không đề cập đến chúng như một tùy chọn ở đây.
để khối
Mã trong một let
khối chỉ được thực thi khi được tham chiếu, việc tải chậm điều này có nghĩa là thứ tự của các khối này không liên quan. Điều này cung cấp cho bạn một lượng lớn năng lượng để cắt giảm thiết lập lặp lại thông qua các thông số kỹ thuật của bạn.
Một ví dụ (cực kỳ nhỏ và nguyên bản) về điều này là:
let(:person) { build(:person) }
subject(:result) { Library.calculate_awesome(person, has_moustache) }
context 'with a moustache' do
let(:has_moustache) { true }
its(:awesome?) { should be_true }
end
context 'without a moustache' do
let(:has_moustache) { false }
its(:awesome?) { should be_false }
end
Bạn có thể thấy điều đó has_moustache
được định nghĩa khác nhau trong mỗi trường hợp, nhưng không cần phải lặp lại subject
định nghĩa. Một điều quan trọng cần lưu ý là let
khối cuối cùng được xác định trong ngữ cảnh hiện tại sẽ được sử dụng. Điều này rất tốt cho việc thiết lập một mặc định được sử dụng cho phần lớn các thông số kỹ thuật, có thể được ghi đè nếu cần.
Ví dụ: kiểm tra giá trị trả về calculate_awesome
nếu được truyền vào một person
mô hình với top_hat
đặt thành true, nhưng không có ria mép sẽ là:
context 'without a moustache but with a top hat' do
let(:has_moustache) { false }
let(:person) { build(:person, top_hat: true) }
its(:awesome?) { should be_true }
end
Một điều cần lưu ý khác về khối lệnh let, chúng không nên được sử dụng nếu bạn đang tìm kiếm thứ gì đó đã được lưu vào cơ sở dữ liệu (tức là Library.find_awesome_people(search_criteria)
) vì chúng sẽ không được lưu vào cơ sở dữ liệu trừ khi chúng đã được tham chiếu. let!
hoặc before
các khối là những gì nên được sử dụng ở đây.
Ngoài ra, đừng bao giờ sử dụng before
để kích hoạt thực thi các let
khối, đây là những gì let!
được tạo ra!
để cho! khối
let!
các khối được thực thi theo thứ tự chúng được xác định (giống như khối trước). Một điểm khác biệt cốt lõi đối với các khối trước là bạn nhận được một tham chiếu rõ ràng đến biến này, thay vì cần phải quay lại các biến phiên bản.
Như với let
các khối, nếu nhiều let!
khối được xác định có cùng tên, thì gần đây nhất là những gì sẽ được sử dụng trong quá trình thực thi. Sự khác biệt cốt lõi là let!
các khối sẽ được thực thi nhiều lần nếu được sử dụng như vậy, trong khi let
khối sẽ chỉ thực thi lần cuối cùng.
trước (: mỗi) khối
before(:each)
là mặc định trước khối, và do đó có thể được tham chiếu before {}
thay vì chỉ định đầy đủ before(:each) {}
mỗi lần.
Sở thích cá nhân của tôi là sử dụng before
các khối trong một vài tình huống cốt lõi. Tôi sẽ sử dụng trước các khối nếu:
- Tôi đang sử dụng chế độ chế giễu, khai gian hoặc tăng gấp đôi
- Có bất kỳ thiết lập có kích thước hợp lý nào (nói chung đây là dấu hiệu cho thấy các đặc điểm ban đầu của bạn chưa được thiết lập chính xác)
- Có một số biến mà tôi không cần tham chiếu trực tiếp nhưng được yêu cầu để thiết lập
- Tôi đang viết các bài kiểm tra bộ điều khiển chức năng trong rails và tôi muốn thực hiện một yêu cầu cụ thể để kiểm tra (tức là
before { get :index }
). Mặc dù bạn có thể sử dụng subject
cho điều này trong nhiều trường hợp, nhưng đôi khi nó có vẻ rõ ràng hơn nếu bạn không yêu cầu tham chiếu.
Nếu bạn thấy mình đang viết các before
khối lớn cho thông số kỹ thuật của mình, hãy kiểm tra các nhà máy của bạn và đảm bảo rằng bạn hiểu đầy đủ các đặc điểm cũng như tính linh hoạt của chúng.
trước (: tất cả) khối
Chúng chỉ được thực thi một lần, trước các thông số kỹ thuật trong ngữ cảnh hiện tại (và con của nó). Những điều này có thể được sử dụng để mang lại lợi ích lớn nếu được viết chính xác, vì có một số tình huống nhất định, điều này có thể cắt giảm việc thực hiện và nỗ lực.
Một ví dụ (hầu như không ảnh hưởng đến thời gian thực thi) là chế nhạo một biến ENV để kiểm tra, mà bạn chỉ cần thực hiện một lần.
Hy vọng rằng sẽ giúp :)