2010-11-26 78 views
3

如何測試模塊的這個小部分,超級? (超是action_dispatch-3.0.1測試/集成...)的模塊包含的投機/請求中攔截RSpec模擬或存根超模型

module ApiDoc 
    def post(path, parameters = nil, headers = nil) 
    super 
    document_request("post", path, parameters, headers) if ENV['API_DOC'] == "true" 
    end 
    ... 
end 

我不希望它運行ActionDispatch ::集成 - 無論如何,但我不知道how to mock or stub super單元測試它。

該模塊僅在規範中使用,並且將具有100%的測試覆蓋率,這證明這些度量類型是無用的。我需要單元測試它。

一個例子,如果需要的話,這是我如何使用模塊ApiDoc

require 'spec_helper' 

describe "Products API" do 
    include ApiDoc ############## <---- This is my module 
    context "POST product" do 
    before do 
     @hash = {:product => {:name => "Test Name 1", :description => "Some data for testing"}} 
    end 

    it "can be done with JSON" do 
     valid_json = @hash.to_json 
     ############### the following 'post' is overriden by ApiDoc 
     post("/products.json",valid_json, 
     {"CONTENT_TYPE" => "application/json", 
     "HTTP_AUTHORIZATION" => ActionController::HttpAuthentication::Basic.encode_credentials("user", "secret")}) 
     response.should be_success 
    end 
    end 
end 

回答

4

您可以檢查,如果該方法被稱爲在「超」級

ActionDispatch::Integration.any_instance.should_receive(:post) 

由於ApiDock只您的測試需要您也可以用alias_method_chain覆蓋post方法:

ActionDispatch::Integration.instance_eval do 
    def post_with_apidoc(path, parameters = nil, headers = nil) 
    post_without_apidoc 
    if ENV['API_DOC'] == "true" 
     document_request("post", path, parameters, headers) 
    end 
    end 
    alias_method_chain :post, :apidoc 
end 
+0

謝謝!我使用摩卡,所以這個工作:`ActionDispatch :: Integration :: Session.any_instance.expects(:post).with xx`,但是我不能模擬ApiDoc.post或-.document_request,就像它說的那樣它的類(ApiDoc)是`RSpec :: Core :: ExampleGroup :: Nested_1`如何在這種情況下嘲笑這些方法?或者我創建一個虛擬類來包含它,以測試這種行爲? – oma 2010-11-26 19:44:30

1

This i這只是對答案的補充。這就是我如何最終測試它

require 'spec_helper' 

describe 'ApiDoc' do 
    include ApiDoc 

    it "should pass the post to super, ActionDispatch" do 
    @path = "path" 
    @parameters = {:param1 => "someparam"} 
    @headers = {:aheader => "someheaders"} 
    ActionDispatch::Integration::Session.any_instance.expects(:post).with(@path, @parameters, @headers) 
    post(@path, @parameters, @headers) 
    end 
end 

class DummySuper 
    def post(path, parameters=nil, headers=nil) 
    #How to verify this is called? 
    end 
end 
class Dummy < DummySuper 
    include ApiDoc 
end 

describe Dummy do 

    it "should call super" do 
    subject.expects(:enabled?).once.returns(true) 
    #how to expect super, the DummySuper.post ? 
    path = "path" 
    parameters = {:param1 => "someparam"} 
    headers = {:aheader => "someheaders"} 
    subject.expects(:document_request).with("post", path, parameters, headers) 
    subject.post(path, parameters, headers) 
    end 
end 

和略有修改的ApiDoc。

module ApiDoc 
    def enabled? 
    ENV['API_DOC'] == "true" 
    end 

    def post(path, parameters = nil, headers = nil) 
    super 
    document_request("post", path, parameters, headers) if enabled? 
    end 

private 
    def document_request(verb, path, parameters, headers) 
    ... 
    end 
end 

我可以確認在第一次測試中super.post,但我仍然無法弄清楚如何做到這一點與我的啞類規格。