2016-11-24 60 views
2

我爲我的合同測試套件使用了Pact寶石(並且非常喜歡!)。我要測試的API服務需要所有請求的授權令牌。如何針對需要身份驗證令牌的API驗證協議?

我知道如何爲我的用戶生成API令牌,但我不知道將令牌放置在Pact工作流中的哪個位置。我搜索了Pact文檔和回購的例子,但沒有任何運氣。

我試着在消費者規範中發送一個POST來生成一個令牌,但是Pact mock服務器不知道如何處理請求和錯誤(正如我所期望的那樣)。

我發現this example它看起來很有希望,特別是能夠使用requestFilteraddHeader方法爲所有請求分配預定義的標頭。

我該如何使用Pact gem這樣的請求過濾器?

如果這不是當前的功能,我有什麼替代方案?

UPDATE:

J_A_X's answer的偉大工程,爲創建與模擬服務器的協定,但它不能滿足一個有效的身份驗證令牌的API服務提供商的期望。更具體地說,我需要在運行pact:verify時動態地將有效的認證令牌插入到協議中。所以,更近一步,但仍需要弄清楚後一部分。

Matthew's answer包含對後面部分似乎有兩種可能的解決方案(pact:verify)的提示。我不願意引入另一個依賴項,所以我很想讓ProxyApp類的例子工作。我不明白我究竟會傳遞給ProxyApp.new()。建議?

回答

1

除非您確實需要,否則實際上不必爲每個協議交互使用真實標記。

通常對於那種東西,我只是創建一個正則表達式來使用頭來驗證某些規則,同時保持它'開放'。在我的節點項目(使用Ruby的二進制在後面),我創建了這兩個實用程序的功能來創建一個對象最小等於模式和另一個對象:

function term(matcher, generate) { 
    if ((typeof matcher === 'undefined') || (typeof generate === 'undefined')) { 
     throw 'Matcher and Generate arguments must be specified to use Term'; 
    } 
    return { 
     "json_class": "Pact::Term", 
     "data": { 
     "generate": generate, 
     "matcher": { 
      "json_class": "Regexp", 
      "o": 0, 
      "s": matcher 
     } 
     } 
    }; 
    } 

    function somethingLike(value) { 
    return { 
     "json_class": "Pact::SomethingLike", 
     "contents": value 
    }; 
    } 

然後,您可以用它在你的DSL定義像這樣:

mockService 
     .given('a form') 
     .uponReceiving('a GET request with a valid auth') 
     .withRequest('get', '/', term('^Bearer (?!null$).+$', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ')) 
     .willRespondWith({ 
     status: 200, 
     headers: {'Content-Type': 'application/json;charset=utf-8'}, 
     body: {worked:true} 
     }); 

在「術語」實用程序有一個正則表達式作爲第一個參數,然後一個例子(應該匹配第一)的測試過程中使用的內容。

我知道這需要在Pact中更好地擴展以使其更易於使用。我希望這有幫助。

+0

謝謝您的完整的答案!你的例子當然可以起作用,儘管它對我來說更像是一種解決方法。我希望有一種內置的方法可以讓我用真正的認證令牌來驗證協議。 – mycargus

+1

好吧,你可以使用它們,但這裏的問題是你現在必須知道在創建交互之前該令牌將會是什麼,然後對它們進行測試。我不知道如何輕鬆創建流程,而不會以某種方式作弊,這基本上與此相同。 最後,問問你自己這個特定的交互檢查在你的提供者的整體測試中是否真的非常重要。在我看來,這不是,因此我的正則表達式;對我來說重要的是業務API以正確的格式/類型返回數據。 –

+0

您的方法非常適合與模擬服務器創建協議,但不符合API服務提供商對有效身份驗證令牌的期望。更具體地說,我需要在運行pact:verify時動態地將有效的認證令牌插入到協議中。那有意義嗎? – mycargus

1

Pact的Ruby實現不直接按照JVM實現支持此操作。

如果您使用的是Pact Provider Proxy gem,則可以查看https://github.com/realestate-com-au/pact/issues/49#issuecomment-65346357https://groups.google.com/forum/#!topic/pact-support/tSyKZMxsECk中討論的一些選項。

一個例子可能看起來像:

class ProxyApp 

    def initialize real_app 
    @real_app = real_app 
    end 

    def call env 
    @real_app.call(env.merge('HTTP_AUTHORIZATION' => '12345')) 
    end 
end 

Pact.service_provider "Some Provider" do 
    app do 
    ProxyApp.new(RealApp) 
    end 

    honours_pact_with "Some Consumer" do 
    #... 
    end 
end 
+0

我會考慮使用提供者代理。謝謝! – mycargus

+0

我現在看到您推薦兩種不同的可能解決方案:(1)使用Pact提供程序代理來驗證針對單獨運行提供程序的協議,或者(2)使用提供程序的pact_helper.rb中的類來合併動態auth標頭到協定覈查。我正在嘗試第二種方法。 – mycargus

+0

謝謝@mycargus,我很想聽聽你如何去。這可能是進入我們的文檔的一個很好的例子,因爲它偶爾會出現。 –