拦截传出的HTTP请求

拦截传出的HTTP请求

问题描述:

所以我正在寻找一个库或拦截来自我的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

你想做什么并不容易,从我的角度来看它没有多大意义。

您正试图测试您的应用程序,但大多数情况下您正在尝试测试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

谢谢一堆:) –