我正在编写一个使用 atlassian 的 JiraRestClient 的应用程序。我无法在每次 Jira 交互中创建此客户端,因此我考虑缓存此客户端。
该客户端每35分钟执行一次登录,因此我想到将其缓存30分钟,然后再次执行登录。
为此,我需要该客户端的单个实例,以便 Jira 交互的所有线程都可以使用它。我创建了一个提供程序类,它将跟踪时间并在实例的创建时间超过 30 分钟时执行登录,确保实例始终登录。
public class JiraRestClientProvider {
private static JiraRestClient jiraRestClient;
private static final long EXPIRATION_TIME = 1800L;
private static long creationTime = Instant.now().getEpochSecond();
public static synchronized JiraRestClient getJiraRestClient() {
if (jiraRestClient == null || Instant.now().getEpochSecond() > creationTime + EXPIRATION_TIME) {
return createJiraRestClient();
}
return jiraRestClient;
}
其中createJiraRestClient
是一个私有(private)方法,用于读取凭据、更新创建时间并更新私有(private)静态变量jiraRestClient
。
另一个类使用此 JiraRestClientProvider
类来执行 Jira 操作,例如创建问题或评论问题等,如下所示:
JiraRestClientProvider.getJiraRestClient().
getIssueClient().createIssue(issueInput).claim().getKey();
或
JiraRestClientProvider.getJiraRestClient().getIssueClient()
.getIssue(issueKey).claim().getCommentsUri().toString();
现在,在为使用此方法的类编写单元测试时,我无法模拟静态方法 getJiraRestClient
,因此无法编写单元测试。
(另外,我无法使用 PowerMock)。
我的问题是,有没有一种方法可以编写我的提供程序类,以便所有线程只有一个新的 JiraRestClient
实例,并且我还可以对其进行单元测试?
最佳答案
是的,你可以。但不是你的设计。
每当您调用时:
JiraRestClientProvider.getJiraRestClient()
你会自动将任何类与单例紧密耦合,这意味着每次你在单元测试中调用被测方法时,它都会调用单例。没有办法解决这个问题,除非你想实现 PowerMock :)。
快速实现这一点的方法是将您的单例包装在一个接口(interface)下,并使用依赖注入(inject)将其注入(inject)您的类中。
编写完整的纯代码,如下所示
interface IJiraClientProvider {
JiraRestClient getJiraRestClient();
}
class Wrapper implements IJiraClientProvider {
JiraRestClient getJiraRestClient() {
return JiraRestClientProvider.getJiraRestClient();
}
}
class YourClass {
private IJiraClientProvider jiraClientProvider
public YourClass(IJiraClientProvider jiraClientProvider) {
this.jiraClientProvider = jiraClientProvider;
}
// now you can unit test your code and mock the dependency
}
当你实例化 YourClass
时,你必须传递包装器:
YourClass cls = new YourClass(new Wrapper());
关于java - 如何实现每30分钟登录一次的客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56670984/