2013-04-14 29 views
35
class TestController < AplicationController 
    #.... 

    private 

    def some_method 
    unless @my_variable.nil? 
     #... 
     return true 
    end 
    end 
end 

Tôi muốn thử nghiệm some_method trực tiếp trong điều khiển spec:RSpec: Làm thế nào để gán biến dụ trong bộ điều khiển đặc tả

require 'spec_helper' 

describe TestController do 
    it "test some_method" 
    phone = Phone.new(...) 
    controller.assign(:my_variable,phone) #does not work 
    controller.send(:some_method).should be_true 
    end 
end 

Làm thế nào tôi có thể thiết lập TestController dụ biến @my_variable từ bộ điều khiển spec?

Trả lời

53

Khi thử nghiệm các phương thức riêng trong bộ điều khiển, thay vì sử dụng send, tôi có xu hướng sử dụng anonymous controller do không muốn gọi trực tiếp phương thức riêng tư, nhưng giao diện cho phương thức riêng tư (hoặc, trong bài kiểm tra bên dưới, có hiệu quả cho giao diện đó) . Vì vậy, trong trường hợp của bạn, có lẽ cái gì đó như:

require 'spec_helper' 

describe TestController do 
    controller do 
    def test_some_method 
     some_method 
    end 
    end 

    describe "a phone test with some_method" do 

    subject { controller.test_some_method } 

    context "when my_variable is not nil" do 
     before { controller.instance_variable_set(:@my_variable, Phone.new(...)) } 
     it { should be_true } 
    end 

    context "when my_variable is nil" do 
     before { controller.instance_variable_set(:@my_variable, nil) } 
     it { should_not be_true } # or should be_false or whatever 
    end  
    end 
end 

Có một số cuộc thảo luận tốt về vấn đề phương pháp tư nhân kiểm tra trực tiếp tại this StackOverflow Q&A, mà đong đưa cho tôi hướng tới sử dụng các bộ điều khiển vô danh, nhưng ý kiến ​​của bạn có thể khác.

+1

Cảm ơn bạn @ Paul cho một giải pháp tốt. – ole

2

Tôi không nghĩ rằng bạn muốn truy cập biến mẫu từ trình điều khiển thông số của mình, vì thông số kỹ thuật nên kiểm tra hành vi, nhưng bạn luôn có thể tạo phương thức riêng tư. Trong trường hợp của bạn cần một cái gì đó như thế này (trong ví dụ này nó không làm cho rất nhiều ý nghĩa):

describe TestController do 
    it "test some_method" 
    phone = Phone.new(...) 
    controller.stub(:some_method).and_return(true) 
    controller.send(:some_method).should be_true 
    end 
end 

Nếu đây không phải là những gì bạn đang tìm kiếm hãy xem này: How to set private instance variable used within a method test?

0

instance_eval là một cách tương đối sạch để thực hiện điều này:

describe TestController do 
    it "test some_method" do 
    phone = Phone.new(...) 
    controller.instance_eval do 
     @my_variable = phone 
    end 
    controller.send(:some_method).should be_true 
    end 
end 

Trong trường hợp này, sử dụng do...end trên instance_eval là quá mức cần thiết, và những ba dòng có thể được rút ngắn xuống còn:

controller.instance_eval {@my_variable = phone} 
Các vấn đề liên quan