2010-10-30 22 views
14

Tôi đang thử nghiệm một phạm vi mà tôi có dựa trên một chuỗi các phạm vi khác. ("public_stream" bên dưới).Cố định các Truy vấn được Chọn trong Rails 3 và Rspec

scope :public, where("entries.privacy = 'public'") 
scope :completed, where("entries.observation <> '' AND entries.application <> ''") 
scope :without_user, lambda { |user| where("entries.user_id <> ?", user.id) } 
scope :public_stream, lambda { |user| public.completed.without_user(user).limit(15) } 

Sử dụng một thử nghiệm như thế này:

it "should use the public, without_user, completed, and limit scopes" do 
     @chain = mock(ActiveRecord::Relation) 
     Entry.should_receive(:public).and_return(@chain) 
     @chain.should_receive(:without_user).with(@user).and_return(@chain) 
     @chain.should_receive(:completed).and_return(@chain) 
     @chain.should_receive(:limit).with(15).and_return(Factory(:entry)) 

     Entry.public_stream(@user) 
    end 

Tuy nhiên, tôi tiếp tục nhận được lỗi này:

Failure/Error: Entry.public_stream(@user) 
undefined method `includes_values' for #<Entry:0xd7b7c0> 

Dường includes_values ​​là một biến thể hiện của các ActiveRecord :: đối tượng Relation nhưng khi tôi cố gắng khai thác nó, tôi vẫn nhận được lỗi tương tự. Tôi đã tự hỏi nếu có ai có kinh nghiệm với các truy vấn chuỗi mới của Rails 3 đang xâu chuỗi? Tôi có thể tìm thấy một loạt các cuộc thảo luận về băm tìm thấy 2.x, nhưng không có gì về cách kiểm tra những gì hiện tại.

+1

Ra khỏi tò mò, nó có tác dụng nếu bạn không sử dụng 'public'?Có một xung đột giữa tên phạm vi của bạn và từ khóa Ruby 'public'. Không chắc chắn đó là vấn đề, nhưng nó muốn được quan tâm trong chuỗi thử nghiệm này thất bại. –

+0

Phạm vi có liên quan trực tiếp đến cơ sở dữ liệu, do đó không có điểm nào trong việc thử nghiệm chúng một cách riêng biệt. Chỉ cần tạo một số bản ghi thực và kiểm tra những gì truy vấn trả về. – RocketR

Trả lời

20

Tôi sử dụng rspec's stub_chain cho việc này. Bạn có thể có thể sử dụng một cái gì đó như:

some_model.rb

scope :uninteresting, :conditions => ["category = 'bad'"], 
         :order => "created_at DESC" 

khiển

@some_models = SomeModel.uninteresting.where(:something_else => true) 

đặc tả

SomeModel.stub_chain(:uninteresting, :where) {mock_some_model} 
0

Hãy thử truyền trên Arel, vì nó có thể là trường hợp phạm vi của nó bị thiếu.

it "should use the public, without_user, completed, and limit scopes" do 
    @chain = Entry 
    @chain.should_receive(:public).and_return(@chain.public) 
    @chain.should_receive(:without_user).with(@user).and_return(@chain.without_user(@user)) 
    @chain.should_receive(:completed).and_return(@chain.completed) 
    @chain.should_receive(:limit).with(15).and_return(Factory(:entry)) 

    Entry.public_stream(@user) 
end 
1

Trước hết, có lẽ bạn nên không được kiểm tra built- trong chức năng Rails.

You should only be writing unit tests for code that you have written yourself (which should be second-nature if you practice TDD) – Rails ships with its own comprehensive suite of unit tests for its built-functionality – there is no point in replicating this.

Theo như lỗi bị ném, tôi nghĩ rằng vấn đề của bạn nằm trên dòng này:

@chain.should_receive(:limit).with(15).and_return(Factory(:entry)) 

Bạn đang mong đợi chuỗi để trả về một Factory, mà hiệu quả sẽ là một thể hiện của ActiveRecord , nhưng trong thực tế every relation returns yet another ActiveRecord::Relation.

Do đó, kỳ vọng của bạn không chính xác và có thể gây ra lỗi đang được ném.

Xin lưu ý rằng phạm vi đó không thực sự trả về các bản ghi mà bạn mong đợi, cho đến khi bạn lặp lại rõ ràng chúng. Ngoài ra, hồ sơ của quan hệ sẽ không bao giờ trả về một bản ghi. Họ sẽ luôn luôn trả lại một mảng trống hoặc một mảng có bản ghi.

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