2013-05-16 47 views
32

Vâng, tôi biết, đó là phương pháp thử tin nó không phải là một ý tưởng tốt (và tôi đọc chủ đề này - http://www.ruby-forum.com/topic/197346 - và một số khác)phương pháp tư nhân kiểm tra trong Ruby (rspec)

Nhưng làm thế nào tôi có thể kiểm tra mã sau đây?

Tôi sử dụng xmpp4r. Trong phương pháp công cộng của tôi #listen tôi bắt đầu nhận jabber thông điệp như sau:

def listen 
    @client.add_message_callback do |m| 
    do_things_with_message(m) 
    end 
end 

private 
def do_things_with_message(m) 
    # 
end 

#add_message_callback - chạy block, khi nhắn đến (trong chủ đề khác nhau)

Vì vậy, thử nghiệm #listen phương pháp rất khó và nó kiểm tra thêm xmpp4r hơn tôi #do_things_with_message

làm thế nào để làm tất cả những quyền và kiểm tra #do_things_with_message? :) (http://www.ruby-forum.com/topic/197346#859664)

Refactor phương pháp riêng cho một đối tượng mới essentialy sẽ như tôi làm cho chúng một cộng đồng (và lớp học với một phương pháp - đó là điên cuồng

EDIT: Đây là thêm một câu hỏi lý thuyết về mã sạch và kiểm tra chính xác. Trong liên kết đầu tiên của tôi, mọi người cho rằng phương pháp riêng tư thử nghiệm kém. Tôi không muốn ăn gian với #send, nhưng tôi cũng không thấy bất kỳ cách nào khả thi để refactor

+0

Đây không phải là một câu hỏi thực sự. Chủ đề bạn liên kết đã cung cấp cho bạn một số kỹ thuật để hoàn thành những gì bạn muốn và một số lời khuyên tốt về cách định hình thiết kế của bạn xung quanh vấn đề. Bạn có thể ăn gian và sử dụng 'send' hoặc chuyển phương thức công khai trong các bài kiểm tra của bạn, hoặc bạn có thể cấu trúc lại. – dbenhur

+0

@ dbenhur Tôi không muốn ăn gian, nhưng tôi cũng không thấy bất kỳ cách nào khả thi để refactor – Andrey

+0

Nếu mã của bạn đủ phức tạp mà bạn cần phải kiểm tra phương pháp riêng (nghĩa là nó không chỉ là một Mô hình đơn giản.tìm kiếm hoặc bất cứ điều gì), sau đó nó có thể rất phức tạp, đủ để có giá trị chiết xuất vào một lớp riêng biệt, anyway. – Jason

Trả lời

75

Bạn có thể gọi phương thức riêng bằng ruby ​​bằng cách sử dụng the send method. Một cái gì đó như thế này:

@my_object = MyObject.new 
@my_object.send(:do_things_with_message, some_message) 

Trong một bài kiểm tra đó sẽ giống như thế:

it "should do a thing" do 
    my_object = MyObject.new 
    my_object.send(:do_things_with_message, some_message) 
    my_object.thing.should == true 
end 
+4

Tôi biết về '# send'. Câu hỏi lý thuyết hơn về mã sạch và kiểm tra đúng ... – Andrey

+0

@Andrey Bạn có thể vui lòng cung cấp bất kỳ tham chiếu nào – Richie

1

Bạn có thể nghe thấy suy nghĩ này trong tất cả các nguồn lực mà bạn đề cập đến, nhưng đúng cách "lý thuyết" để làm điều đó sẽ kiểm tra rằng @client nhận được add_message_callback và sau đó gián tiếp kiểm tra các phương pháp riêng của bạn bằng các thử nghiệm tích hợp. Toàn bộ các điểm kiểm tra đơn vị là bạn có thể thay đổi thực hiện, và các bài kiểm tra của bạn vẫn sẽ vượt qua

+0

"đó là kiểm tra @client nhận add_message_callback" - có thể bạn đã ... nhưng vẫn đang thử nghiệm gem xmpp4r, máy chủ jabber và mạng của tôi, vv công việc thực tế và đầu ra thực sự làm '# do_things_with_message'. '# add_message_callback' chỉ khởi chạy chủ đề mới – Andrey

+1

Việc thêm một người nghe không phải là mã đá quý, nếu không bạn sẽ không phải viết nó. Nếu bạn muốn kiểm tra phương thức riêng của bạn, hoặc là công khai nó hoặc sử dụng 'send (: do_things_with_message, args)' – enthrops

12

Bỏ qua vấn đề hay không, bạn nên được thử nghiệm một phương pháp riêng, nó rất có thể trong Ruby tạm thời đặt phương thức riêng tư thành công khai. Dưới đây là những gì tôi có nghĩa là:

# Metaprogrammatical magic to temporarily expose 
# a Class' privates (methods). 
class Class 
    def publicize_methods 
    saved_private_instance_methods = self.private_instance_methods 
    self.class_eval { public *saved_private_instance_methods } 
    yield 
    self.class_eval { private *saved_private_instance_methods } 
    end 
end 

Bạn sẽ sử dụng publicize_methods như thế này:

ClassToTest.publicize_methods do 
    ... 
    do_private_things_with_message(m).should ??? 
    ... 
end 
Các vấn đề liên quan