2010-11-11 35 views
45

Tôi có một mô hình với một phương pháp riêng tư tôi muốn spec với RSpec,
làm thế nào để bạn thường làm gì? Bạn chỉ thử nghiệm phương thức gọi là phương thức riêng tư?
hoặc cũng là thông số riêng tư? nếu vậy, làm thế nào để bạn làm gì?Làm thế nào để xác định một phương pháp riêng

Trả lời

109

Tôi luôn luôn thực hiện phương pháp này: Tôi muốn kiểm tra API công khai mà lớp học của tôi hiển thị.

Nếu bạn có phương pháp riêng tư, bạn chỉ gọi cho họ từ các phương thức công khai mà bạn tiếp cận với các lớp khác. Do đó, nếu bạn kiểm tra xem các phương thức công cộng đó có hoạt động như mong đợi trong mọi điều kiện hay không, bạn cũng đã chứng minh rằng các phương thức riêng tư mà họ sử dụng cũng hoạt động.

Tôi sẽ thừa nhận rằng tôi đã gặp một số phương pháp riêng tư đặc biệt phức tạp. Trong trường hợp này rất khó, bạn muốn kiểm tra chúng, bạn có thể làm điều này:

@obj.send(:private_method) 
+1

Cảm ơn sự giúp đỡ của bạn, tôi đồng ý rằng việc kiểm tra phương pháp công khai cũng chứng tỏ phương thức riêng tư cũng hoạt động. Điều đó đang được nói ở đây tôi thực sự muốn thử nghiệm phương pháp riêng và giải pháp của bạn hoạt động như một sự quyến rũ, Cảm ơn! – Mike

+2

Dưới đây là một cách tiếp cận thú vị khác http://kailuowang.blogspot.com/2010/08/testing-private-methods-in-rspec.html – gucki

+1

Tôi có một hook before_save trong mô hình của mình để lưu một mã thông báo riêng cho cơ sở dữ liệu thông qua một tư nhân phương thức 'make_private_token'. Phương thức 'make_private_token' sử dụng các phương thức lớp công khai, không phải theo cách khác, vì vậy cách duy nhất tôi có thể kiểm tra nó là với phương thức 'send'. Không thấy bất cứ điều gì 'cực đoan' về điều đó ... – Starkers

6

Đối với những phương pháp riêng mà cần mã số bảo hiểm (tạm thời hoặc vĩnh viễn), sử dụng rspec-context-private gem để tạm thời làm cho các phương pháp công tư trong một bối cảnh.

gem 'rspec-context-private' 

Nó hoạt động bằng cách thêm ngữ cảnh được chia sẻ vào dự án của bạn.

RSpec.shared_context 'private', private: true do 

    before :all do 
    described_class.class_eval do 
     @original_private_instance_methods = private_instance_methods 
     public *@original_private_instance_methods 
    end 
    end 

    after :all do 
    described_class.class_eval do 
     private *@original_private_instance_methods 
    end 
    end 

end 

Sau đó, nếu bạn vượt qua :private như siêu dữ liệu đến một khối describe, những phương pháp riêng sẽ được công khai trong bối cảnh đó.

class Example 
    private def foo 
    'bar' 
    end 
end 

describe Example, :private do 
    it 'can test private methods' do 
    expect(subject.foo).not eq 'bar' 
    end 
end 
+0

Tôi không biết nếu bạn duy trì đá quý này nữa, nhưng tài liệu của bạn không có khối mã về khai báo shared_context. Vì vậy, tôi đã không thể làm cho nó hoạt động đơn giản bằng cách đọc tài liệu. Sau khi thêm vào khối này, nó hoạt động như mong đợi. – istrasci

0

Nếu bạn đang muốn thử nghiệm một kỳ vọng về một phương pháp riêng, câu trả lời được chấp nhận sẽ không thực sự làm việc (ít nhất là không mà tôi biết, vì vậy tôi mở cửa cho chỉnh vào thời điểm đó). Những gì tôi đã làm thay thậm chí còn filthier - trong các thử nghiệm riêng của mình, chỉ cần tiếp xúc với phương pháp này bằng cách xác định lại nó:

def object_to_test.my_private_method 
    super 
end 

Hoạt động trên Ruby 1,8, không thể bình luận về bất kỳ của runtimes mới hơn.

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