Как реализовать клиента, который должен войти в систему каждые 30 минут? - PullRequest
0 голосов
/ 19 июня 2019

Я пишу приложение, которое использует JiraRestClient от atlassian.Я не могу создать этот клиент при каждом взаимодействии с 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 это приватный метод, который считывает учетные данные, обновляет время создания и обновляет приватную статическую переменную jiraRestClient.

Другой класс использует этот класс JiraRestClientProvider для выполнения действий Jira, таких как создание проблем или комментирование проблемы и т. Д., Следующим образом:

JiraRestClientProvider.getJiraRestClient().
getIssueClient().createIssue(issueInput).claim().getKey();

или

JiraRestClientProvider.getJiraRestClient().getIssueClient()
            .getIssue(issueKey).claim().getCommentsUri().toString();

Теперь, при написании модульного теста для класса, использующего этот метод, я не могу высмеять статический метод getJiraRestClient и поэтому не могу написать модульные тесты.(Кроме того, я не могу использовать PowerMock).

Мой вопрос: есть ли способ, которым я могу написать свой класс провайдера таким образом, чтобы у меня был только один и свежий экземпляр JiraRestClient для всех потоков, и я могутакже юнит-тест это?

1 Ответ

1 голос
/ 19 июня 2019

Да, вы можете.Но не с вашим дизайном.

Всякий раз, когда вы вызываете:

JiraRestClientProvider.getJiraRestClient() 

, вы автоматически тесно связываете любой класс с одноэлементным, что означает, что каждый раз, когда вы вызываете тестируемый метод в модульных тестахэто назовет Синглтон.Обойти это невозможно, если, конечно, вы не захотите реализовать PowerMock :).

Быстрый выигрыш для этого - обернуть ваш синглтон под интерфейсом и использовать инъекцию зависимости, чтобы внедрить его в ваши классы.

При написании полного простого кода это будет выглядеть так:

 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()); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...