java - 如何实现每30分钟登录一次的客户端?

标签 java design-patterns junit singleton jira

我正在编写一个使用 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/

相关文章:

java - 在 Eclipse 中手动终止测试套件时不会调用 @AfterClass 方法

java - Spring Boot 和 Junit 的 Maven 依赖

java - String 是如何调用构造函数的?

java - 将时间戳字符串解析为Java.sql.timestamp

c# - 密封类和单例

php - 使用对象而不是数组

c# - 从文本文件中读取,并将每一行拆分为不同的数组或列表

java - 在 JUnit 中初始化私有(private)字段

java - Spring 安全java.lang.AbstractMethodError

java - 编译时的 Tomcat JSP 优化