2009-03-20 32 views
11

Chained Tôi muốn gọi một named_scope rằng sẽ chỉ trả lại một bản ghi, nhưng named_scope trả về một mảng, đó không phải là một vấn đề lớn như tôi chỉ có thể chuỗi nó với .first:Stubbing phương pháp với RSpec

Model.named_scope(param).first 

và điều này hoạt động, những gì tôi đang đấu tranh là làm thế nào để stub cuộc gọi xích. Có ai có một tài liệu tham khảo hoặc một câu trả lời về cách tôi sẽ đi về việc đạt được điều này với Rspec chế giễu?

Trả lời

16

Tôi đã tìm ra điều gì đó.

Client.stub!(:named_scope).and_return(@clients = mock([Client])) 
@clients.stub!(:first).and_return(@client = mock(Client)) 

cho phép tôi gọi điều khiển của tôi:

@client = Client.named_scope(param).first 

Nó hoạt động, nhưng là có một giải pháp tốt hơn?

EDIT:

Việc phát hành rspec 1.2.6 cho phép chúng ta sử dụng stub_chain nghĩa bây giờ nó có thể là:

Client.stub_chain(:named_scope, :chained_call).and_return(@clients = [mock(Client)]) 

Đây là đỉnh đầu của tôi, như mọi khi kiểm tra các api cho chi tiết cụ thể:)

+2

Có thể di chuyển phần EDIT: ở đầu câu trả lời – Sam

+0

Cảm ơn rất nhiều, Chris! Nó đã giúp rất nhiều !! – ep3static

1

Tôi cho rằng đây là thông số kỹ thuật của bộ điều khiển?

Đề xuất của riêng bạn sẽ hoạt động tốt. Một khả năng khác là di chuyển cuộc gọi named_scope bên trong mô hình của bạn, để tránh hoàn toàn vấn đề. Điều này cũng phù hợp với lời khuyên "mô hình chất béo, bộ điều khiển mỏng".

0

Tôi nghĩ bạn đã thực hiện điều khiển bộ điều khiển mỏng bằng cách đặt truy vấn vào một phạm vi được đặt tên, nơi nó có thể được sử dụng lại. Dưới đây là một số mã tôi đã sử dụng trước khi tôi bắt đầu sử dụng phạm vi được đặt tên.

def mock_comm(stubs={}) 
    @mock_comm ||= mock_model(Comm, stubs) 
    end 

    describe "responding to GET index" do 

    it "should expose all comms as @comms" do 
     Comm.should_receive(:find).with(:all).and_return([mock_comm]) 
     get :index 
     assigns[:comms].should == [mock_comm] 
    end 
# ... 

Tôi có thể viết mã khá giống với những gì bạn đã có, nhưng có thể đặt nó trong một trình trợ giúp cho phép tôi sử dụng lại nó. Một thứ khác là sử dụng một khung mocking khác có thể cho phép bạn kiểm soát nhiều hơn. Có một cái nhìn tại Ryan Bates 'railscast trên RSpec - đó là một chút cũ bây giờ nhưng vẫn còn một số ý tưởng tốt trong đó. phiên bản

2

tốt hơn

Client.stub!(:named_scope).and_return(@clients = mock([Client])) 
@clients.stub!(:first).and_return(@client = mock(Client)) 

sẽ là:

Client.should_receive(:named_scope).with(param).and_return do 
    record = mock_model(Comm) 
    record.should_receive(:do_something_else) 
    [record] 
end 
2

Câu hỏi đặt ra là khá cũ và do đó có rất ít cải tiến trong cách stubbing thể được thực hiện. Bây giờ bạn có thể sử dụng phương thức stub_chain để tạo một chuỗi các cuộc gọi phương thức. Ví dụ:

@client = Client.named_scope(param).first

có thể được stubbed với:

Client.stub_chain(:named_scope,:first).and_return(@client = mock(Client))

Nhiều ví dụ về stub_chaining:

describe "stubbing a chain of methods" do 
    subject { Object.new } 

    context "given symbols representing methods" do 
    it "returns the correct value" do 
     subject.stub_chain(:one, :two, :three).and_return(:four) 
     subject.one.two.three.should eq(:four) 
    end 
    end 

    context "given a string of methods separated by dots" do 
    it "returns the correct value" do 
     subject.stub_chain("one.two.three").and_return(:four) 
     subject.one.two.three.should eq(:four) 
    end 
    end 
end 

or please have a look at:

Dài sống rspecs !!! :)

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