2014-12-07 15 views
10

Tôi đang gặp phải một thời gian tồi khi tìm kiếm trên SO/Google trường hợp cụ thể này. Tôi có một mô-đun với các hàm và để sử dụng chúng, bạn phải tạo một Lớp bao gồm/mở rộng Mô-đun tùy thuộc vào nếu bạn muốn các phương thức thể hiện hoặc các phương thức lớp.Kiểm tra Mô-đun Ruby với rspec

module A 
    def say_hello name 
    "hello #{name}" 
    end 

    def say_bye 
    "bye" 
    end 
end 

Tôi có thể thử nghiệm mô-đun này bằng cách sử dụng rspec như thế nào?

Tôi có một cái gì đó như thế này, và tôi không chắc điểm nào tôi nên tạo lớp và mở rộng Mô-đun.

describe A do 
    class MyClass 
    extend A 
    end 

    before(:each) { @name = "Radu" } 

    describe "#say_hello" do 
    it "should greet a name" do 
     expect(Myclass.say_hello(@name)).to eq "hello Radu" 
    end 
    end 
end 

Cảm ơn bạn!

+1

phương pháp của bạn không trả lại giá trị này. Bạn nên kiểm tra xem nó có đặt nó hay không, do đó phương thức 'puts' được gọi một lần với đối số' hello Radu' – zishe

+0

@zishe yep 'say_hello (@name)' return 'nil'. –

+1

Đây là một ví dụ ngớ ngẩn. Tôi có phương pháp trả lại mọi thứ. Mối quan tâm của tôi là làm thế nào để sử dụng mở rộng trong rspec – radubogdan

Trả lời

24

Bạn có thể tạo một lớp vô danh trong các thử nghiệm của bạn:

describe A do 
    let(:extended_class) { Class.new { extend A } } 
    let(:including_class) { Class.new { include A } } 

    it "works" do 
    # do stuff with extended_class.say_hello 
    # do stuff with including_class.new.say_hello 
    end 
end 

Để xem một cái gì đó tương tự trong mã thực tế, tôi đã sử dụng chiến lược này cho testing my attr_extras lib.

Điều đó nói rằng, includeextend là các tính năng tiêu chuẩn của Ruby, vì vậy tôi sẽ không kiểm tra xem mọi mô-đun có hoạt động cả khi bao gồm và khi mở rộng - thường là một.

Nếu bạn tạo một lớp có tên trong bài kiểm tra, giống như bạn làm trong câu hỏi của mình, tôi tin rằng lớp đó sẽ tồn tại trên toàn cầu trong suốt thời gian chạy thử nghiệm của bạn. Vì vậy, lớp này sẽ bị rò rỉ giữa mọi thử nghiệm của bộ thử nghiệm của bạn, có khả năng gây xung đột ở đâu đó.

Nếu bạn sử dụng let để tạo một lớp ẩn danh, nó sẽ chỉ có sẵn trong thử nghiệm cụ thể này. Không có hằng số toàn cầu trỏ đến nó có thể xung đột với các thử nghiệm khác.

+0

Tôi vẫn nhận được 'phương thức undefined' my_method 'cho # ', nhưng có lẽ là lỗi của tôi . Cảm ơn câu trả lời nhanh của bạn. – radubogdan

+0

@radubogdan Tôi đã thử dán [mã chính xác này (liên kết Gist)] (https://gist.github.com/henrik/8d400883a99779de4926) vào một bài kiểm tra RSpec hiện có và nó trôi qua, vì vậy có thể có điều gì khác không đúng? –

+0

Vâng, chắc chắn có điều gì đó sai, nhưng tôi không thể tìm thấy cái gì. Có thể là spec_helper? (Tôi tạo ra spec_helper bằng cách sử dụng rspec --init, phiên bản rspec là 3.1.7) – radubogdan

0

Để giúp độc giả ra trong tương lai, đây là một ví dụ tôi đã đi sử dụng giải pháp @ 's Henrik-n:

# slim_helpers.rb 
module SlimHelpers 

    # resourceToTitle converts strings like 'AWS::AutoScaling::AutoScalingGroup' 
    # to 'Auto Scaling Group' 
    def resourceToTitle(input) 
    input.split('::')[-1].gsub(/([A-Z])/, ' \1').lstrip 
    end 

end 

# slim_helpers_spec.rb 
require_relative '../slim_helpers' 

describe SlimHelpers do 

    # extended class 
    let(:ec) { Class.new { extend SlimHelpers } } 

    it "converts AWS resource strings to titles" do 
    out = ec.resourceToTitle('AWS::AutoScaling::AutoScalingGroup') 
    expect(out).to eq 'Auto Scaling Group' 
    end 
end 
+0

Bạn cũng có thể sử dụng 'Class.extend (SlimHelpers)' nếu bạn cần kiểm tra các phương thức lớp. – czerasz

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