2012-02-03 20 views
6

Với mã bên dưới:Rails/RSpec - viết spec cho phương pháp đại biểu (allow_nil tùy chọn)

(1) Làm thế nào bạn sẽ đi về cách viết một spec để kiểm tra: allow_nil => lựa chọn sai?

(2) Có đáng để viết một đặc tả để kiểm tra không?

class Event < ActiveRecord::Base 
    belongs_to :league 

    delegate :name, :to => :league, :prefix => true, :allow_nil => false 
end 

describe Event do 

    context 'when delegating methods to league object' do 
    it { should respond_to(:league_name) } 
    end 

end 

Nó sẽ thực sự được tốt đẹp nếu bạn có thể mở rộng shoulda làm:

it { should delegate(:name).to(:league).with_options(:prefix => true, :allow_nil => false) } 
+1

Bạn có thể muốn xem xét điều này - một người khác đã làm công việc cho bạn. https://gist.github.com/txus/807456 – weltschmerz

Trả lời

9

Theo tài liệu cho delegate ray mô-đun:

Nếu đối tượng delegate là con số không một ngoại lệ được nêu ra, và điều đó xảy ra không có vấn đề cho dù nil phản ứng với phương pháp được giao. Bạn có thể nhận được một số không thay thế bằng tùy chọn: allow_nil.

tôi sẽ tạo ra một đối tượng tổ chức sự kiện event với một con số không , hoặc thiết lập event.league = nil, sau đó cố gắng gọi event.name, và kiểm tra xem nó đặt ra một ngoại lệ, vì đó là những gì được cho là xảy ra khi allow_nil là sai (mà cũng là mặc định). Tôi biết rspec có thành ngữ này để kiểm tra ngoại lệ:

lambda{dangerous_operation}.should raise_exception(optional_exception_class) 

Tôi không chắc liệu ifa có cấu trúc này, mặc dù có are some articles, kinda old, about how to get this behavior in shoulda.

Tôi nghĩ rằng đây là giá trị thử nghiệm nếu nó là hành vi mà người dùng của lớp này có thể mong đợi hoặc giả định sẽ xảy ra - mà tôi nghĩ rằng có lẽ đúng trong trường hợp này. Tôi sẽ không mở rộng thử nghiệm "nên ủy nhiệm", bởi vì điều đó có vẻ phụ thuộc vào việc thực hiện nhiều hơn: bạn thực sự đang nói sự kiện của mình sẽ tăng ngoại lệ nếu bạn cố gọi #name khi có giải đấu nil. Nó thực sự không quan trọng đối với người dùng của sự kiện như thế nào bạn đang làm cho điều đó xảy ra. Tôi thậm chí sẽ đi xa, nếu bạn muốn khẳng định và ghi chú về hành vi này, để kiểm tra rằng Event#name có cùng ngữ nghĩa như League#name, mà không cần đề cập đến bất cứ điều gì về delegate, vì đây là cách tiếp cận tập trung vào hành vi.

Xây dựng các thử nghiệm dựa trên cách mã của bạn hoạt động, không phải cách mã của bạn hoạt động - thử nghiệm theo cách này là tài liệu tốt hơn cho những người vấp ngã vào thử nghiệm của bạn, vì họ quan tâm hơn đến câu hỏi "Tại sao sự kiện của tôi lại xuất hiện? " hoặc "Điều gì có thể khiến Sự kiện bị ném?" hơn "sự kiện này có được ủy quyền không?".

Bạn có thể đánh dấu loại tình huống này bằng cách tưởng tượng những gì thất bại có thể xảy ra nếu bạn thay đổi mã của mình theo cách mà người dùng Sự kiện không quan tâm. Nếu họ không quan tâm đến nó, thử nghiệm không nên phá vỡ khi bạn thay đổi nó. Điều gì sẽ xảy ra nếu bạn muốn, ví dụ, tự mình xử lý ủy nhiệm, bằng cách viết hàm #name mà lần đầu tiên ghi nhật ký hoặc tăng số lượt truy cập và thì đại biểu đến ? bằng cách kiểm tra hành vi nâng cao ngoại lệ, bạn được bảo vệ khỏi thay đổi này, nhưng bằng cách kiểm tra xem Sự kiện có phải là đại biểu hay không, bạn sẽ phá vỡ thử nghiệm đó khi thực hiện thay đổi này - và vì vậy thử nghiệm của bạn không xem xét thực sự là gì về cuộc gọi đến #name.

Dù sao, đó chỉ là nói chuyện trong hộp xà phòng. tl; dr: kiểm tra nó nếu đó là hành vi ai đó có thể dựa vào.Bất cứ thứ gì không được kiểm tra là mèo của Shroedinger: bị vỡ và không bị vỡ cùng một lúc. Thật ra, phần lớn thời gian này có thể được chấp nhận: Đó là vấn đề về hương vị cho dù bạn muốn nói điều gì đó nghiêm ngặt và dứt khoát về cách hệ thống hoạt động, hoặc chỉ để cho nó là "hành vi không xác định".

+0

Bạn sẽ phải kiểm tra ngoại lệ là một RuntimeError nếu không, đơn giản là không ủy nhiệm sẽ nâng cao một phương thức không tìm thấy. – fivetwentysix

2

Vì vậy, một vài điều ở đây về việc có hay không kiểm tra điều này:

1) Tôi không nghĩ có bất kỳ điều gì sai trái khi xác định hành vi này. Nếu bạn có người dùng cần phải tìm hiểu phần mềm/thư viện của bạn, nó thường rất hữu ích để đảm bảo rằng tất cả các phương pháp của bạn là một phần của hợp đồng phải đối mặt với công chúng của bạn là spec'd. Nếu bạn không muốn thực hiện phần này của api của mô hình này, tôi có thể khuyên bạn nên thực hiện ủy nhiệm theo cách thủ công để không hiển thị thêm nhiều phương thức cho thế giới bên ngoài hơn là bạn cần.

2) Thông số kỹ thuật sắp xếp này giúp đảm bảo rằng hợp đồng mà bạn có với đối tượng mà ủy quyền của bạn vẫn được thực thi. Điều này đặc biệt hữu ích nếu bạn đang sử dụng sơ khai và mocks trong các bài kiểm tra của bạn, vì họ thường thực hiện cùng một hợp đồng, vì vậy ít nhất bạn biết khi hợp đồng này thay đổi.

Về cách bạn kiểm tra phần allow_nil của nó, tôi đồng ý với Matt, ý tưởng tốt nhất là đảm bảo rằng giải đấu là không, sau đó cố gắng gọi tên trên giải đấu. Điều này bạn có thể kiểm tra để đảm bảo rằng nil được trả về.

Hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan