2013-02-19 33 views
10

Tôi có một chức năng, mà chấp nhận một khối, mở một tập tin, sản lượng và lợi nhuận:Làm thế nào để kiểm tra một chức năng mà phải mất một khối với rspec

def start &block 
    .....do some stuff 
    File.open("filename", "w") do |f| 
     f.write("something") 
     ....do some more stuff 
     yield 
    end 
end 

Tôi cố gắng để viết một bài kiểm tra cho nó bằng cách sử rspec . Làm thế nào để tôi File.open để nó thông qua một đối tượng f (được cung cấp bởi tôi) cho khối thay vì cố gắng để mở một tập tin thực tế? Một cái gì đó như:

it "should test something" do 
    myobject = double("File", {'write' => true}) 
    File.should_receive(:open).with(&blk) do |myobject| 
     f.should_receive(:write) 
     blk.should_receive(:yield) (or somethig like that) 
    end 
end 
+1

Thật khó để kiểm tra điều này bởi vì những gì bạn muốn kiểm tra là nội bộ của phương pháp. Cách tệp của bạn tương tác với bất kỳ thứ gì bên ngoài phương thức? Từ ví dụ của bạn, bạn không sử dụng tệp bên ngoài phương thức và bạn cũng không thể tạo ra nó. Nếu một cái gì đó bên ngoài chức năng này cần các tập tin, sau đó có lẽ bạn nên xem xét đi qua các đối tượng tập tin vào phương pháp (tiêm phụ thuộc). Sau đó, bạn có thể thử các tập tin không có vấn đề. Nếu bạn cần phải kiểm tra một cái gì đó về tập tin đó, có lẽ bạn nên xem xét phá vỡ nó ra thành một phương pháp riêng biệt? – Raj

+0

Cảm ơn ... đã làm một cái gì đó như thế, chia thành nhiều phương pháp, stubbed vài chức năng như File.stub (mở) .and_yield (my_double), vv – constantine1

Trả lời

3

Tôi nghĩ rằng những gì bạn đang tìm kiếm là yield matchers, ví dụ:

it "should test something" do 
    # just an example 
    expect { |b| my_object.start(&b) }.to yield_with_no_args 
end 
+0

Làm thế nào để tôi stub File.open để cung cấp một đối tượng giả bên trong hàm (bắt đầu) đang được thử nghiệm? – constantine1

+0

Hãy để tôi nghỉ ngơi - làm thế nào để tôi đệ trình File.open để cung cấp một đối tượng giả cho khối của nó, để tôi có thể kiểm tra một cái gì đó như f.should_receive (: write) .với ("những gì cần được ghi vào tập tin") – constantine1

+0

Tôi đã bỏ lỡ bình luận của bạn và chỉ hôm nay nhấp vào "phản hồi". Về cơ bản File.open gửi khối * self * (thử chạy 'đặt f.inspect' từ bên trong khối), vì vậy việc nhạo báng' File.should_receive (: write) 'sẽ hoạt động. Xin lỗi vì trả lời muộn nhưng hy vọng điều này sẽ hữu ích cho ai đó :) – Amir

1

lựa chọn nào khác của bạn là để còn sơ khai: mở với một đối tượng mới của File, như vậy:

file = File.new 
allow(File).to receive(:open) { file } 
file.each { |section| expect(section).to receive(:write) } 
# run your method 
+0

Hãy cẩn thận với điều này. Tôi đã tìm thấy trong kinh nghiệm của tôi rằng nếu bạn sử dụng RSPec stubs/mocks trên các lớp hệ thống cơ bản, như 'File', nó có xu hướng dẫn đến rất nhiều vấn đề. Ví dụ, nếu bạn sử dụng đá quý VCR trong các bài kiểm tra của bạn, nó sẽ phá vỡ trong thời trang ngoạn mục nếu bạn cho phép (File) .để nhận được khá nhiều bất cứ điều gì. – Jazz

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