2016-02-05 176 views
0

所以我正在尋找一個庫或攔截來自我的Java應用程序的任何傳出HTTP請求的方式?爲什麼?因爲我想單元測試API集成,並且因爲我正在使用該API的庫(包裝器),所以我無法修改它的任何代碼。這不是我的代碼實際上是在發送HTTP請求。攔截傳出的HTTP請求

因此,我需要攔截它們,查看它們並根據API文檔聲明它們是正確的。

我試過在網上尋找,但我找不到確切的東西,我正在尋找。大多數圖書館都會讓我這樣做,只要我自己正確配置請求,但我不能這樣做,因爲它們是由API包裝器製作的,而不是我的代碼。

乾杯

P.S一些示例代碼

String path = "/some/path"; 
String repoOwner = "John Doe"; 
String repoName = "John repo" 

GitHubClient client = new GitHubClient(); 
client.setCredentials(this.username, this.password); 

RepositoryService repositoryService = new RepositoryService(client); 
CommitService commitService = new CommitService(client); 

Repository repo = repositoryService.getRepository(repoOwner, repoName); 

List<RepositoryCommit> commits = commitService.getCommits(repo, null, path); 

這將使用API​​的包裝以獲得在給定庫的所有提交。假設我想查看這個代碼正在做的HTTP請求,然後我想單元測試它們並聲明它們是正確的。我會怎麼做?有沒有什麼方法可以攔截它們,捕捉它們像是一種異常,並對它們做些什麼,如斷言?

+0

使用可以使用一些攔截器或方面來做到這一點。 – Frank

+0

@Frank,請您詳細說明一下嗎?我從來沒有聽說過這些。 –

+0

如果它不是一個偏離主題,請提供一些代碼並更好地解釋你正在嘗試做什麼。在再次閱讀您的問題後,我不確定我是否理解正確。 – Frank

回答

0

你想做什麼並不容易,從我的角度來看它沒有多大意義。

您正試圖測試您的應用程序,但大多數情況下您正在嘗試測試GitHubClient庫

如果我是你,我只會在你的測試中使用mocks並驗證輸入參數。所以測試會喜歡這樣(使用mockito):

List<RepositoryCommit> commits = new ArrayList<>(); 
commits.add(new RepositoryCommit(....)); 
commits.add(new RepositoryCommit(....)); 
when(commitService.getCommits(repo, null, path)).thenReturn(commits); 

您避免庫測試的方式。

如果你想實際調查圖書館做什麼 - 什麼要求它發送和正在發生的事情 - 我會建議你經過庫代碼,發現其中請求實際上是建立和公正的地方在調試模式下運行您的應用程序並在那裏添加斷點

如果你真的想處理(例如記錄,複製......)真正的請求到GitHub,即使在生產中,你也可以使用AspectJ。這將改變字節碼,以便你可以包裝特定的方法調用。再次,您將不得不在GitHub庫中找到真正的GitHub(我認爲是HTTP)調用並將該方面附加到該調用的位置。在方面,你基本上聲明瞭你想攔截的方法以及你想在它的調用之前或之後要做什麼。我不是一個真正的專家在這方面,所以我不能爲你提供更多的信息 - 有一個關於方面的教程 - https://eclipse.org/aspectj/doc/next/progguide/starting.html

其他選項也安裝一些網絡手錶的工具,像wireshark

編輯

其他選項如何避免代價高昂的調用GitHub的是創建一個簡單的包裝是這樣的:

public class GitHubServiceImpl implements GitHubService { 
    private Rpository repo; 

    /** other methods **/ 

    @Override 
    public List<RepositoryCommit> getAllCommits(String path) { 
     return commitService.getCommits(repo, null, path)); 
    } 
} 

這裏是要測試實際的服務。

public class CommitService { 

    private GitHubService gitHubService; 

    private String path; 

    public List<RepositoryCommit> getAll() { 
     return gitHubService.getAllCommits(path); 
    } 

} 

和集成測試創建特殊的實施GitHubService接口:

public class TestGitHubService implements GitHubService { 

    private Map<String, RepositoryCommit> preArrangedCommits; 
    /** other methods **/ 

    public void setPreArrangedCommits(Map<String, RepositoryCommit> preArrangedCommits) { 
     this.preArrangedCommits = preArrangedCommits; 
    } 

    @Override 
    public List<RepositoryCommit> getAllCommits(String path) { 
     return preArrangedCommits; 
    } 
} 

,並在測試呼叫:

public class CommitServiceIntegrationTest { 
    // @Autowired, @Bean maybe? 
    private CommitService commitService; 

    // @Autowired, @Bean maybe? 
    private GitHubService gitHubService; 

    public void testGetAll() { 
     Map<String, RepositoryCommit> preArrangedCommits = new HashMap<>(); 
     preArrangedCommits.put("path/", new RepositoryCommit(...)); 
     gitHubService.setPreArrangedCommits(preArrangedCommits); 
     List<RepositoryCommit> commits = commitService.getAll(); 
     assertEquals(commits, preArrangedCommits); 
    } 
} 

我會走這條路。

弗蘭克

+0

我想單元測試的主要原因是如果有人改變我的代碼,即我將庫實現到產品中的方式,他們將無法打破它。我也想避免實際運行我正在測試的方法,因爲它們需要很長時間才能與GitHub進行通信,而GitHub在包含數百個測試的大型項目中並不理想。我們使用Jenkins和Sonar,當我們推到主回購庫時,所有測試都會自動運行。我基本上正在尋找一種方法,通過避免等待GitHub服務器的響應來減少運行測試所需的時間。 –

+0

查看答案更新 – Frank

+0

謝謝一堆:) –