2014-08-29 16 views
7

Làm cách nào để xóa hoàn toàn một lớp khỏi bộ nhớ trong Ruby?Làm cách nào để đặt lại định nghĩa lớp trong Ruby?

Tôi có hai tập Tôi đang làm việc với:

# foo.rb 
require 'expensive_library' 

class Foo < ExpensiveLibrary::Plugin 
    ... 
end 

và:

# foo_tests.rb 
require 'foo' 
require 'test/unit' 

class foo_tests < Test::Unit::TestCase 
    def test_foo_meets_spec_1 
    ... 
    end 
    def test_foo_meets_deprecated_spec 
    ... 
    end 
end 

ExpensiveLibrary là tốn kém; phải mất hơn 15 giây để tải. Đây là cách quá lâu để liên tục chạy các bài kiểm tra trong quá trình phát triển (phần còn lại của bộ thử nghiệm mất ít hơn 1 giây).

Tôi đã làm việc xung quanh thời gian tải của thư viện đắt tiền bằng cách bắt đầu Pry và viết một hàm tải hai tệp và gọi Test::Unit:Autorunner.run. Điều này vẫn có một tạm dừng 15 giây trong lần chạy thử đầu tiên, nhưng các lần chạy thử nghiệm tiếp theo mất ít hơn 1 giây.

Tuy nhiên, có hai vấn đề:

  1. Pry phàn nàn về tất cả các phương pháp trên Foo và Foo_tests được xác định lại
  2. khi tôi loại bỏ phương thức từ tập tin nguồn, nó vẫn được xác định trong môi trường thử nghiệm của tôi, tạo ra các lỗi giả mạo.

Dựa trên các câu hỏi về Stack Overflow khác (như "How to undefine class in Ruby?"), tôi đã thử gọi Object.constants.remove(:Foo)Object.constants.remove(:Foo_tests). Tôi không còn nhận được phương pháp xác định lại lỗi, nhưng bây giờ các autorunner chạy các bài kiểm tra nhiều lần, bao gồm cả các bài kiểm tra loại bỏ.

Điều tôi muốn là chạy thử nghiệm đã sửa đổi mà không cần tải lại ExpensiveLibrary. Việc xác định các lớp thử nghiệm là cách tôi thấy để làm điều đó, nhưng tôi không biết làm thế nào. Các giải pháp khác có thể tốt hơn.

+0

Cảm ơn bạn đã chỉnh sửa. –

Trả lời

0

OK, chỉ cần nhấn mạnh ở đây, bởi vì tôi không chắc chắn chính xác những gì bạn đang cố gắng, nhưng bạn đã thử undef hoặc undef_method? Họ không làm việc trực tiếp trên các lớp học, nhưng nếu bạn undef các phương pháp gọi các xét nghiệm bạn không muốn làm có thể nó sẽ làm việc cho bạn?

0

Bạn có thể hack bằng đường dẫn tải (Adding a directory to $LOAD_PATH (Ruby)).

  • tạo ra một số thư mục như ./tests/fake_implementations/
  • thêm nó vào $ LOAD_PATHS
  • add có nộp expensive_library.rb với một số thực hiện giả nhẹ của ExpensiveLibrary
  • sau đó require 'expensinsive_library' sẽ được tải tập tin này thay cho một gốc.
1

Dường như với tôi rằng những gì bạn đang tìm kiếm là trình tải trước như hoặc thậm chí là một trình cụ thể hơn như rspec-preloader. Khi sử dụng một trình nạp trước, bạn sẽ phải yêu cầu tập tin của bạn 'foo' trong một file spec/spec_helper.rb, mà bạn có thể đã có:

# spec/spec_helper.rb 
require 'foo' 

# ... 

Các spec_helper nên tải toàn bộ môi trường ứng dụng của bạn. Có thể cho rằng, nó đắt hơn khi chạy thử nghiệm một lần.Nhưng bằng cách sử dụng trình tải trước, bạn chỉ phải yêu cầu tất cả mã sau khi.

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