2009-07-22 24 views
32

Có cách nào để mở Kernel.sleep trong kịch bản rspec không?RSpec: stubbing Kernel :: ngủ?

+0

Bạn đang tìm kiếm một cái gì đó xa hơn Kernel :: stubs (: sleep) –

+0

Tôi tưởng tượng anh ta muốn nó hoạt động và không ngủ, có thể làm chậm kiểm tra của mình ... – Rich

Trả lời

43

Nếu bạn đang gọi trong ngữ cảnh của một đối tượng, bạn nên đặt nó lên đối tượng, như vậy:

class Foo 
    def self.some_method 
    sleep 5 
    end 
end 

it "should call sleep" do 
    Foo.stub!(:sleep) 
    Foo.should_receive(:sleep).with(5) 
    Foo.some_method 
end 

Điều quan trọng là, để ngủ trên giường bất cứ điều gì "tự" là trong bối cảnh mà giấc ngủ được gọi.

+1

Làm việc tuyệt vời cho tôi, chúc mừng! – opsb

+0

Kéo đối tượng đang thử nghiệm không phải là một ý tưởng hay. Ví dụ: xem: http://robots.thoughtbot.com/don-t-stub-the-system-under-test – georgebrock

+1

@georgebrock vì lý do không liên quan, phải không? Tôi tin [this] (http://stackoverflow.com/a/27749263/52499) là cách truyền đạt ý định tốt nhất. Và phải sử dụng cú pháp mới hơn. 'allow_any_instance_of (Object) .để nhận ((ngủ)' –

2

Nếu bạn đang sử dụng Mocha, sau đó một cái gì đó như thế này sẽ làm việc:

def setup 
    Kernel.stubs(:sleep) 
end 

def test_my_sleepy_method 
    my_object.take_cat_nap! 
    Kernel.assert_received(:sleep).with(1800) #should take a half-hour paower-nap 
end 

Hoặc nếu bạn đang sử dụng rr:

def setup 
    stub(Kernel).sleep 
end 

def test_my_sleepy_method 
    my_object.take_cat_nap! 
    assert_received(Kernel) { |k| k.sleep(1800) } 
end 

Bạn lẽ không nên thử nghiệm nhiều hơn các vấn đề phức tạp với các bài kiểm tra đơn vị. Tuy nhiên, trên các thử nghiệm tích hợp, hãy sử dụng Kernel.sleep thực, điều này sẽ giúp bạn tìm ra các vấn đề về luồng phức tạp.

4

Trong rspec tinh khiết:

before do 
    Kernel.stub!(:sleep) 
end 

it "should sleep" do 
    Kernel.should_receive(:sleep).with(100) 
    Object.method_to_test #We need to call our method to see that it is called 
end 
+8

Để làm rõ, vì điều này không hiệu quả với tôi ngay lập tức, bạn phải gọi Kernel ngủ, để thử nó theo cách này. Chỉ cần gọi ngủ trực tiếp thất bại –

+0

Có, phương pháp bạn gọi sẽ có giấc ngủ trong đó. – nitecoder

0

tôi cần phải còn sơ khai yêu cầu và sau khi tìm kiếm lâu tôi phát hiện ra rằng cách duy nhất mà làm việc cho tôi là thế này ngủ

def method_using_sleep 
    sleep 
    sleep 0.01 
end 

it "should use sleep" do 
    @expectations = mock('expectations') 
    @expectations.should_receive(:sleep).ordered.with() 
    @expectations.should_receive(:sleep).ordered.with(0.01) 

    def sleep(*args) 
    @expectations.sleep(*args) 
    end 

    method_using_sleep 
end 
0

Tôi không thể nhận các giải pháp khác ở đây để hoạt động. Có lẽ một cái gì đó đã thay đổi trong cách ngủ được xử lý trong phiên bản mới hơn của Ruby, hoặc cái gì khác.

Những gì tôi đã làm là để khỉ vá đối tượng lớp vì dường như đây là những gì nhận được cuộc gọi ngủ. Vì vậy, tôi chỉ cần thêm điều này:

class Object 
    def sleep(*args) 
    end 
end 

Vì vậy, phương pháp ngủ hiện không có gì thay cho điều gì đó. Có thể có một số cách để chế nhạo này tốt hơn, nhưng tôi đã không thể tìm thấy một giải pháp tốt mà không chế giễu các sleep metohd của mỗi đối tượng duy nhất có khả năng sử dụng nó.

+0

Vui lòng xem giải pháp của tôi dưới đây. rspec-mock là ở đây vì vậy bạn không cần phải khỉ vá – Benj

11

Khi cuộc gọi đến sleep không nằm trong một đối tượng (trong khi thử nghiệm một công việc cào chẳng hạn), bạn có thể thêm như sau trong một trước khi khối (rspec 3 cú pháp)

allow_any_instance_of(Object).to receive(:sleep)