2013-04-06 43 views
16

Tôi đang mở rộng một thư viện hiện có bằng cách tạo một lớp con mở rộng đến lớp thư viện.Làm thế nào tôi có thể thử siêu ruby ​​bằng rspec?

Trong lớp con, tôi đã có thể kiểm tra hầu hết các chức năng trong phương pháp initialize, nhưng không thể giả lập số gọi super. Lớp trẻ trông giống như dưới đây.

class Child < SomeLibrary 
    def initialize(arg) 
     validate_arg(arg) 
     do_something 
     super(arg) 
    end 

    def validate_arg(arg) 
     # do the validation 
    end 

    def do_something 
     @setup = true 
    end 
end 

Tôi có thể viết test rspec (bằng mocha) sao cho tôi có thể thử gọi super? Lưu ý rằng tôi đang thử nghiệm chức năng của phương pháp initialize trong lớp Child. Tôi có phải tạo đường dẫn mã riêng biệt không gọi số super khi được cung cấp thêm đối số không?

Trả lời

15

Bạn không thể giả mạo super và bạn không nên. Khi bạn thử một cái gì đó, bạn đang xác minh rằng một tin nhắn cụ thể được nhận, và super không phải là một thông điệp - đó là một từ khóa.

Thay vào đó, tìm ra hành vi của lớp này sẽ thay đổi nếu cuộc gọi super bị thiếu và viết ví dụ về các bài tập và xác minh hành vi đó.

+1

Điều đó có nghĩa tôi không thể viết bài kiểm tra rspec cho khởi tạo? Có thực hành không tốt để viết thử nghiệm đơn vị cho phương thức khởi tạo không? Nhân tiện, tôi đang mở rộng thư viện trình kết nối cơ sở dữ liệu. Nếu tôi không viết bài kiểm tra đơn vị, nhưng viết thử nghiệm tích hợp, tôi chỉ nghĩ rằng nó là lạ nếu kiểm tra rspec yêu cầu kết nối với cơ sở dữ liệu thực. –

+0

Điều đó không có ý nghĩa với tôi vì sao chúng ta không thể chế nhạo siêu. Nó có vẻ hữu ích để làm như vậy để kiểm tra đúng cách hành vi khởi tạo trong sự cô lập, và chắc chắn siêu là một tin nhắn được gửi đến một thể hiện của một lớp, không? –

+1

Không, 'super' là _not_ một tin nhắn được gửi đến một thể hiện của một lớp. Tôi biết không có cấu trúc lập trình siêu lập trình ruby ​​nào có thể làm được điều này, và thậm chí nếu nó là, tôi vẫn không tin rằng đó là một ý tưởng hay. –

1

Một cách tốt để kiểm tra này là để thiết lập một kỳ vọng của một số hành động được thực hiện bởi lớp cha - ví dụ:

class Some::Thing < Some 
def instance_method 
    super 
end 
end 

và lớp siêu:

class Some 
    def instance_method 
    another_method 
    end 

    def self.another_method # not private! 
    'does a thing' 
    end 
end 

nay kiểm tra:

describe '#instance_method' do 
    it 'appropriately triggers the super class method' do 
     sawm = Some::Thing.new 
     expect(sawm).to receive(:another_method) 
     sawm.instance_method 
    end 
end 

Tất cả điều này xác định số siêu đó được gọi trên lớp học tối cao

Tính hữu ích của mẫu này phụ thuộc vào cách bạn cấu trúc các thử nghiệm của bạn/kỳ vọng của bạn về đột biến của lớp học/lớp phái sinh theo phương pháp super đang được áp dụng.

Ngoài ra - chú ý tới classinstance phương pháp, bạn sẽ cần phải điều chỉnh allowsexpects phù

YMMV