Repository: jenkinsci/prometheus-plugin
Pull request #365 (2022-02-25 22:56:10)

Use Mockito Inline instead of PowerMock and cleanup dependencies
Fixes broken build.

### Changes proposed

The project build was broken because the PowerMock libraries version has not been set. However, PowerMock is not compatible with Mockito 3.X, so there is not sense to fix it. Instead the Mockito Inline library is added which supports mocking static methods. The tests were updated to use the new API.

The Jenkins version has been updated to the latest available LTS. Every LTS is provided with a `bom-X.Y.Z` artifact which should be used to determine versions of the most common dependencies (e.g. the `junit` plugin). Whenever the LTS is updated to a newer version, the `bom` artifact must be updated too. All unnecessary dependencies have been removed.

The `Jenkins#getInstance` method is deprecated, so all occurrences have been replaced with `Jenkins#get`.

### Checklist

- [x] Includes tests covering the new functionality?
- [x] Ready for review
- [x] Follows CONTRIBUTING rules

### Notify

@markyjackson-taulia



Patch:
diff --git a/pom.xml b/pom.xml
index 095355b..3ba603d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.jenkins-ci.plugins</groupId>
     <artifactId>plugin</artifactId>
-    <version>4.35</version>
+    <version>4.37</version>
     <relativePath />
   </parent>
 
@@ -17,27 +17,20 @@
   <inceptionYear>2016</inceptionYear>
 
   <properties>
-    <jenkins.version>2.222.4</jenkins.version>
+    <!-- when updated the io.jenkins.tools.bom:bom-X.Y.Z must be updated too -->
+    <jenkins.version>2.319.3</jenkins.version>
     <java.level>8</java.level>
-    <prometheus.simpleClientJava.version>0.15.0</prometheus.simpleClientJava.version>
-    <workflow.api.version>1138.v619fd5201b_2f</workflow.api.version>
-    <workflow.job.version>1167.v8fe861b_09ef9</workflow.job.version>
-    <workflow.step.version>622.vb_8e7c15b_c95a_</workflow.step.version>
-    <jenkins.metrics.version>4.1.6.1</jenkins.metrics.version>
-    <jenkins.junit.version>1.55</jenkins.junit.version>
-    <jenkins.diskUsage.version>0.10</jenkins.diskUsage.version>
-    <jenkins.structs.version>1.24</jenkins.structs.version>
-    <gson.version>2.9.0</gson.version>
+
+    <prometheus.simpleclient.version>0.15.0</prometheus.simpleclient.version>
+    <slf4j.version>1.7.36</slf4j.version>
+
+    <cloudbees-disk-usage-simple.version>0.10</cloudbees-disk-usage-simple.version>
+    <metrics.version>4.1.6.1</metrics.version>
+    <pipeline-rest-api.version>2.21</pipeline-rest-api.version>
+
+    <assertj-core.version>3.22.0</assertj-core.version>
     <JUnitParams.version>1.1.1</JUnitParams.version>
-    <httpcore.version>4.4.15</httpcore.version>
     <system-lambda.version>1.2.1</system-lambda.version>
-    <assertj-core.version>3.22.0</assertj-core.version>
-    <slf4j.version>1.7.36</slf4j.version>
-    <pipeline.rest.api.version>2.21</pipeline.rest.api.version>
-    <workflow.support.version>813.vb_d7c3d2984a_0</workflow.support.version>
-    <pipeline.graph.analysis.version>1.12</pipeline.graph.analysis.version>
-    <script.security.version>1131.v8b_b_5eda_c328e</script.security.version>
-    <jackson2.version>2.13.1-240.vfedd8f46cfde</jackson2.version>
   </properties>
 
   <organization>
@@ -82,145 +75,86 @@
     </pluginRepository>
   </pluginRepositories>
 
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>io.jenkins.tools.bom</groupId>
+        <artifactId>bom-2.319.x</artifactId>
+        <version>1155.v77b_fd92a_26fc</version>
+        <scope>import</scope>
+        <type>pom</type>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
   <dependencies>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins</groupId>
-      <artifactId>jackson2-api</artifactId>
-      <version>${jackson2.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins.workflow</groupId>
-      <artifactId>workflow-api</artifactId>
-      <version>${workflow.api.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins.pipeline-stage-view</groupId>
-      <artifactId>pipeline-rest-api</artifactId>
-      <version>${pipeline.rest.api.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins.workflow</groupId>
-      <artifactId>workflow-job</artifactId>
-      <version>${workflow.job.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins.workflow</groupId>
-      <artifactId>workflow-support</artifactId>
-      <version>${workflow.support.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins.workflow</groupId>
-      <artifactId>workflow-step-api</artifactId>
-      <version>${workflow.step.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins</groupId>
-      <artifactId>pipeline-graph-analysis</artifactId>
-      <version>${pipeline.graph.analysis.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins</groupId>
-      <artifactId>structs</artifactId>
-      <version>${jenkins.structs.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins</groupId>
-      <artifactId>script-security</artifactId>
-      <version>${script.security.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore</artifactId>
-      <version>${httpcore.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins</groupId>
-      <artifactId>metrics</artifactId>
-      <version>${jenkins.metrics.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-      <version>${gson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>io.prometheus</groupId>
-      <artifactId>simpleclient_hotspot</artifactId>
-      <version>${prometheus.simpleClientJava.version}</version>
-    </dependency>
     <dependency>
       <groupId>io.prometheus</groupId>
       <artifactId>simpleclient</artifactId>
-      <version>${prometheus.simpleClientJava.version}</version>
+      <version>${prometheus.simpleclient.version}</version>
     </dependency>
     <dependency>
       <groupId>io.prometheus</groupId>
       <artifactId>simpleclient_common</artifactId>
-      <version>${prometheus.simpleClientJava.version}</version>
+      <version>${prometheus.simpleclient.version}</version>
     </dependency>
     <dependency>
       <groupId>io.prometheus</groupId>
       <artifactId>simpleclient_dropwizard</artifactId>
-      <version>${prometheus.simpleClientJava.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jenkins-ci.plugins</groupId>
-      <artifactId>junit</artifactId>
-      <version>${jenkins.junit.version}</version>
+      <version>${prometheus.simpleclient.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.jenkins-ci.plugins</groupId>
-      <artifactId>cloudbees-disk-usage-simple</artifactId>
-      <version>${jenkins.diskUsage.version}</version>
-      <optional>true</optional>
+      <groupId>io.prometheus</groupId>
+      <artifactId>simpleclient_hotspot</artifactId>
+      <version>${prometheus.simpleclient.version}</version>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>${slf4j.version}</version>
     </dependency>
+
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-jdk14</artifactId>
-      <version>${slf4j.version}</version>
+      <groupId>org.jenkins-ci.plugins</groupId>
+      <artifactId>cloudbees-disk-usage-simple</artifactId>
+      <version>${cloudbees-disk-usage-simple.version}</version>
+      <optional>true</optional>
     </dependency>
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>log4j-over-slf4j</artifactId>
-      <version>${slf4j.version}</version>
+      <groupId>org.jenkins-ci.plugins</groupId>
+      <artifactId>junit</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>jcl-over-slf4j</artifactId>
-      <version>${slf4j.version}</version>
+      <groupId>org.jenkins-ci.plugins</groupId>
+      <artifactId>metrics</artifactId>
+      <version>${metrics.version}</version>
     </dependency>
-
-    <!-- Test only -->
     <dependency>
-      <groupId>pl.pragmatists</groupId>
-      <artifactId>JUnitParams</artifactId>
-      <version>${JUnitParams.version}</version>
-      <scope>test</scope>
+      <groupId>org.jenkins-ci.plugins.pipeline-stage-view</groupId>
+      <artifactId>pipeline-rest-api</artifactId>
+      <version>${pipeline-rest-api.version}</version>
     </dependency>
+
     <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-mockito2</artifactId>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>${assertj-core.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
+      <groupId>pl.pragmatists</groupId>
+      <artifactId>JUnitParams</artifactId>
+      <version>${JUnitParams.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-core</artifactId>
-      <version>2.2</version>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
+      <artifactId>mockito-inline</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -229,11 +163,5 @@
       <version>${system-lambda.version}</version>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.assertj</groupId>
-      <artifactId>assertj-core</artifactId>
-      <version>${assertj-core.version}</version>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 </project>
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/JenkinsStatusCollector.java b/src/main/java/org/jenkinsci/plugins/prometheus/JenkinsStatusCollector.java
index 83ac3cc..8b1a238 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/JenkinsStatusCollector.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/JenkinsStatusCollector.java
@@ -24,7 +24,7 @@ public class JenkinsStatusCollector extends Collector {
                 .namespace(namespace)
                 .help("Is Jenkins ready to receive requests")
                 .create();
-        Jenkins jenkins = Jenkins.getInstance();
+        Jenkins jenkins = Jenkins.get();
         jenkinsUp.set(jenkins.getInitLevel() == hudson.init.InitMilestone.COMPLETED ? 1 : 0);
         samples.addAll(jenkinsUp.collect());
 
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java b/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java
index 2848db4..a07b527 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java
@@ -68,7 +68,7 @@ public class PrometheusConfiguration extends GlobalConfiguration {
     }
 
     public static PrometheusConfiguration get() {
-        Descriptor configuration = Jenkins.getInstance().getDescriptor(PrometheusConfiguration.class);
+        Descriptor configuration = Jenkins.get().getDescriptor(PrometheusConfiguration.class);
         return (PrometheusConfiguration) configuration;
     }
 
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java b/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java
index abe57cc..5e8f38d 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java
@@ -50,7 +50,7 @@ public class PrometheusAction implements UnprotectedRootAction {
 
     private boolean hasAccess() {
         if (PrometheusConfiguration.get().isUseAuthenticatedEndpoint()) {
-            return Jenkins.getInstance().hasPermission(Metrics.VIEW);
+            return Jenkins.get().hasPermission(Metrics.VIEW);
         }
         return true;
     }
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/util/Jobs.java b/src/main/java/org/jenkinsci/plugins/prometheus/util/Jobs.java
index 4bed873..ecb5c4c 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/util/Jobs.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/util/Jobs.java
@@ -6,9 +6,14 @@ import jenkins.model.Jenkins;
 import java.util.List;
 import java.util.function.Consumer;
 
-public class Jobs {
+public final class Jobs {
+
+    private Jobs() {
+        // prevents creating new instances
+    }
+
     public static void forEachJob(Consumer<Job> consumer) {
-        List<Job> jobs = Jenkins.getInstance().getAllItems(Job.class);
+        List<Job> jobs = Jenkins.get().getAllItems(Job.class);
         if (jobs != null) {
             for (Job item : jobs) {
                 consumer.accept(item);


Test patch:
diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/DiskUsageCollectorTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/DiskUsageCollectorTest.java
index 6763992..f57aa72 100644
--- a/src/test/java/org/jenkinsci/plugins/prometheus/DiskUsageCollectorTest.java
+++ b/src/test/java/org/jenkinsci/plugins/prometheus/DiskUsageCollectorTest.java
@@ -9,10 +9,17 @@ import static org.hamcrest.Matchers.is;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.withSettings;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-import static org.powermock.api.mockito.PowerMockito.when;
 
+import com.cloudbees.simplediskusage.DiskItem;
+import com.cloudbees.simplediskusage.JobDiskItem;
+import com.cloudbees.simplediskusage.QuickDiskUsagePlugin;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+import io.prometheus.client.Collector;
+import io.prometheus.client.Collector.MetricFamilySamples;
 import java.io.IOException;
 import java.nio.file.FileStore;
 import java.nio.file.Path;
@@ -21,99 +28,92 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
-
+import jenkins.model.Jenkins;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeDiagnosingMatcher;
 import org.jenkinsci.plugins.prometheus.util.ConfigurationUtils;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.MockedStatic;
 import org.mockito.junit.MockitoJUnitRunner;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-
-import com.cloudbees.simplediskusage.DiskItem;
-import com.cloudbees.simplediskusage.JobDiskItem;
-import com.cloudbees.simplediskusage.QuickDiskUsagePlugin;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableMap;
 
-import io.prometheus.client.Collector;
-import io.prometheus.client.Collector.MetricFamilySamples;
-import jenkins.model.Jenkins;
-
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(MockitoJUnitRunner.StrictStubs.class)
+@RunWith(MockitoJUnitRunner.class)
 public class DiskUsageCollectorTest {
 
     @Mock
-    Jenkins jenkins;
-
+    private Jenkins jenkins;
     @Mock
-    QuickDiskUsagePlugin quickDiskUsagePlugin;
+    private QuickDiskUsagePlugin quickDiskUsagePlugin;
 
-    final DiskUsageCollector underTest = new DiskUsageCollector();
+    private DiskUsageCollector underTest;
+
+    @Before
+    public void setUp() {
+        underTest = new DiskUsageCollector();
+    }
 
     @Test
-    @PrepareForTest(ConfigurationUtils.class)
     public void shouldNotProduceMetricsWhenDisabled() {
-        mockStatic(ConfigurationUtils.class);
-        when(ConfigurationUtils.getCollectDiskUsage()).thenReturn(false);
+        try (MockedStatic<ConfigurationUtils> configurationUtils = mockStatic(ConfigurationUtils.class)) {
+            configurationUtils.when(() -> ConfigurationUtils.getCollectDiskUsage()).thenReturn(false);
 
-        final List<MetricFamilySamples> samples = underTest.collect();
+            final List<MetricFamilySamples> samples = underTest.collect();
 
-        assertThat(samples, is(empty()));
+            assertThat(samples, is(empty()));
+        }
     }
 
     @Test
-    @PrepareForTest({ Jenkins.class, ConfigurationUtils.class })
-    public void shouldProdueMetrics() throws IOException {
-        mockStatic(Jenkins.class, ConfigurationUtils.class);
-        when(ConfigurationUtils.getNamespace()).thenReturn("foo");
-        when(ConfigurationUtils.getSubSystem()).thenReturn("bar");
-        when(ConfigurationUtils.getCollectDiskUsage()).thenReturn(true);
-        when(Jenkins.get()).thenReturn(jenkins);
-        when(jenkins.getPlugin(QuickDiskUsagePlugin.class)).thenReturn(quickDiskUsagePlugin);
-
-        final FileStore store = mock(FileStore.class, "the file store");
-        given(store.getTotalSpace()).willReturn(4711L);
-        given(store.getUsableSpace()).willReturn(1337L);
-
-        final DiskItem dir = mock(DiskItem.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));
-        given(dir.getDisplayName()).willReturn("dir name");
-        given(dir.getUsage()).willReturn(11L);
-        mockFileStore(dir, store);
-        final CopyOnWriteArrayList<DiskItem> directories = new CopyOnWriteArrayList<>();
-        directories.add(dir);
-        given(quickDiskUsagePlugin.getDirectoriesUsages()).willReturn(directories);
-
-        final JobDiskItem job = mock(JobDiskItem.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));
-        given(job.getFullName()).willReturn("job name");
-        given(job.getUrl()).willReturn("/job");
-        given(job.getUsage()).willReturn(7L);
-        mockFileStore(job, store);
-        final CopyOnWriteArrayList<JobDiskItem> jobs = new CopyOnWriteArrayList<>();
-        jobs.add(job);
-        given(quickDiskUsagePlugin.getJobsUsages()).willReturn(jobs);
-
-        final List<MetricFamilySamples> samples = underTest.collect();
-
-        assertThat(samples, containsInAnyOrder(
-            gauges("foo_bar_disk_usage_bytes", containsInAnyOrder(
-                sample(ImmutableMap.of("file_store", "the file store", "directory", "dir"), equalTo(11. * 1024))
-            )),
-            gauges("foo_bar_job_usage_bytes", containsInAnyOrder(
-                sample(ImmutableMap.of("file_store", "the file store", "jobName", "job name", "url", "/job"), equalTo(7. * 1024))
-            )),
-            gauges("foo_bar_file_store_capacity_bytes", containsInAnyOrder(
-                sample(ImmutableMap.of("file_store", "the file store"), equalTo(4711.))
-            )),
-            gauges("foo_bar_file_store_available_bytes", containsInAnyOrder(
-                sample(ImmutableMap.of("file_store", "the file store"), equalTo(1337.))
-            ))
-        ));
+    public void shouldProduceMetrics() throws IOException {
+        try (MockedStatic<ConfigurationUtils> configurationUtils = mockStatic(ConfigurationUtils.class);
+             MockedStatic<Jenkins> jenkinsStatic = mockStatic(Jenkins.class)) {
+            configurationUtils.when(() -> ConfigurationUtils.getNamespace()).thenReturn("foo");
+            configurationUtils.when(() -> ConfigurationUtils.getSubSystem()).thenReturn("bar");
+            configurationUtils.when(() -> ConfigurationUtils.getCollectDiskUsage()).thenReturn(true);
+            jenkinsStatic.when(() -> Jenkins.get()).thenReturn(jenkins);
+            when(jenkins.getPlugin(QuickDiskUsagePlugin.class)).thenReturn(quickDiskUsagePlugin);
+
+            final FileStore store = mock(FileStore.class, "the file store");
+            given(store.getTotalSpace()).willReturn(4711L);
+            given(store.getUsableSpace()).willReturn(1337L);
+
+            final DiskItem dir = mock(DiskItem.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));
+            given(dir.getDisplayName()).willReturn("dir name");
+            given(dir.getUsage()).willReturn(11L);
+            mockFileStore(dir, store);
+            final CopyOnWriteArrayList<DiskItem> directories = new CopyOnWriteArrayList<>();
+            directories.add(dir);
+            given(quickDiskUsagePlugin.getDirectoriesUsages()).willReturn(directories);
+
+            final JobDiskItem job = mock(JobDiskItem.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));
+            given(job.getFullName()).willReturn("job name");
+            given(job.getUrl()).willReturn("/job");
+            given(job.getUsage()).willReturn(7L);
+            mockFileStore(job, store);
+            final CopyOnWriteArrayList<JobDiskItem> jobs = new CopyOnWriteArrayList<>();
+            jobs.add(job);
+            given(quickDiskUsagePlugin.getJobsUsages()).willReturn(jobs);
+
+            final List<MetricFamilySamples> samples = underTest.collect();
+
+            assertThat(samples, containsInAnyOrder(
+                gauges("foo_bar_disk_usage_bytes", containsInAnyOrder(
+                    sample(ImmutableMap.of("file_store", "the file store", "directory", "dir"), equalTo(11. * 1024))
+                )),
+                gauges("foo_bar_job_usage_bytes", containsInAnyOrder(
+                    sample(ImmutableMap.of("file_store", "the file store", "jobName", "job name", "url", "/job"), equalTo(7. * 1024))
+                )),
+                gauges("foo_bar_file_store_capacity_bytes", containsInAnyOrder(
+                    sample(ImmutableMap.of("file_store", "the file store"), equalTo(4711.))
+                )),
+                gauges("foo_bar_file_store_available_bytes", containsInAnyOrder(
+                    sample(ImmutableMap.of("file_store", "the file store"), equalTo(1337.))
+                ))
+            ));
+        }
     }
 
     private static final void mockFileStore(DiskItem item, FileStore store) throws IOException {
diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java
index 144ba94..0391038 100644
--- a/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java
+++ b/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java
@@ -3,16 +3,22 @@ package org.jenkinsci.plugins.prometheus.rest;
 import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
 import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
 import static java.net.HttpURLConnection.HTTP_OK;
-import static org.junit.Assert.assertEquals;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import io.prometheus.client.exporter.common.TextFormat;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-
 import javax.servlet.ServletException;
-
+import jenkins.metrics.api.Metrics;
+import jenkins.model.Jenkins;
 import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration;
 import org.jenkinsci.plugins.prometheus.service.PrometheusMetrics;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -20,98 +26,92 @@ import org.kohsuke.stapler.HttpResponse;
 import org.kohsuke.stapler.StaplerRequest;
 import org.kohsuke.stapler.StaplerResponse;
 import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
-import io.prometheus.client.exporter.common.TextFormat;
-import jenkins.metrics.api.Metrics;
-import jenkins.model.Jenkins;
-
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Jenkins.class})
-// PowerMockIgnore needed for: https://github.com/powermock/powermock/issues/864
-@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*"})
+@RunWith(MockitoJUnitRunner.class)
 public class PrometheusActionTest {
 
     @Mock
     private Jenkins jenkins;
-
     @Mock
     private PrometheusConfiguration configuration;
 
+    private MockedStatic<Jenkins> jenkinsStatic;
+
     @Before
     public void setUp() {
-        PowerMockito.mockStatic(Jenkins.class);
-        PowerMockito.when(Jenkins.getInstance()).thenReturn(jenkins);
-        PowerMockito.when(jenkins.getDescriptor(PrometheusConfiguration.class)).thenReturn(configuration);
-        PowerMockito.when(configuration.getAdditionalPath()).thenReturn("prometheus");
+        jenkinsStatic = mockStatic(Jenkins.class);
+        jenkinsStatic.when(() -> Jenkins.get()).thenReturn(jenkins);
+        when(jenkins.getDescriptor(PrometheusConfiguration.class)).thenReturn(configuration);
+        when(configuration.getAdditionalPath()).thenReturn("prometheus");
+    }
+
+    @After
+    public void tearDown() {
+        jenkinsStatic.close();
     }
 
     @Test
     public void shouldThrowExceptionWhenDoesNotMatchPath() throws IOException, ServletException {
         // given
         PrometheusAction action = new PrometheusAction();
-        StaplerRequest request = Mockito.mock(StaplerRequest.class);
+        StaplerRequest request = mock(StaplerRequest.class);
         String url = "";
-        Mockito.when(request.getRestOfPath()).thenReturn(url);
+        when(request.getRestOfPath()).thenReturn(url);
 
         // when
         HttpResponse actual = action.doDynamic(request);
 
         // then
         AssertStaplerResponse.from(actual)
-                .call()
-                .assertHttpStatus(HTTP_NOT_FOUND);
+            .call()
+            .assertHttpStatus(HTTP_NOT_FOUND);
     }
 
     @Test
     public void shouldThrowExceptionWhenAuthenticationEnabledAndInsufficientPermission() throws IOException, ServletException {
         // given
         PrometheusAction action = new PrometheusAction();
-        StaplerRequest request = Mockito.mock(StaplerRequest.class);
+        StaplerRequest request = mock(StaplerRequest.class);
         String url = "prometheus";
-        Mockito.when(request.getRestOfPath()).thenReturn(url);
-        Mockito.when(configuration.isUseAuthenticatedEndpoint()).thenReturn(true);
-        Mockito.when(jenkins.hasPermission(Metrics.VIEW)).thenReturn(false);
+        when(request.getRestOfPath()).thenReturn(url);
+        when(configuration.isUseAuthenticatedEndpoint()).thenReturn(true);
+        when(jenkins.hasPermission(Metrics.VIEW)).thenReturn(false);
 
         // when
         HttpResponse actual = action.doDynamic(request);
 
         // then
         AssertStaplerResponse.from(actual)
-                .call()
-                .assertHttpStatus(HTTP_FORBIDDEN);
+            .call()
+            .assertHttpStatus(HTTP_FORBIDDEN);
     }
 
     @Test
     public void shouldReturnMetrics() throws IOException, ServletException {
         // given
         PrometheusAction action = new PrometheusAction();
-        PrometheusMetrics prometheusMetrics = Mockito.mock(PrometheusMetrics.class);
+        PrometheusMetrics prometheusMetrics = mock(PrometheusMetrics.class);
         String responseBody = "testMetric";
-        Mockito.when(prometheusMetrics.getMetrics()).thenReturn(responseBody);
+        when(prometheusMetrics.getMetrics()).thenReturn(responseBody);
         action.setPrometheusMetrics(prometheusMetrics);
-        StaplerRequest request = Mockito.mock(StaplerRequest.class);
+        StaplerRequest request = mock(StaplerRequest.class);
         String url = "prometheus";
-        Mockito.when(request.getRestOfPath()).thenReturn(url);
+        when(request.getRestOfPath()).thenReturn(url);
 
         // when
         HttpResponse actual = action.doDynamic(request);
 
         // then
         AssertStaplerResponse.from(actual)
-                .call()
-                .assertHttpStatus(HTTP_OK)
-                .assertContentType(TextFormat.CONTENT_TYPE_004)
-                .assertHttpHeader("Cache-Control", "must-revalidate,no-cache,no-store")
-                .assertBody(responseBody);
+            .call()
+            .assertHttpStatus(HTTP_OK)
+            .assertContentType(TextFormat.CONTENT_TYPE_004)
+            .assertHttpHeader("Cache-Control", "must-revalidate,no-cache,no-store")
+            .assertBody(responseBody);
     }
 
-
     private static class AssertStaplerResponse {
         private final StaplerResponse response;
         private final HttpResponse httpResponse;
@@ -119,10 +119,10 @@ public class PrometheusActionTest {
 
         private AssertStaplerResponse(HttpResponse httpResponse) throws IOException {
             this.httpResponse = httpResponse;
-            this.response = Mockito.mock(StaplerResponse.class);
+            this.response = mock(StaplerResponse.class);
             stringWriter = new StringWriter();
             PrintWriter writer = new PrintWriter(stringWriter);
-            Mockito.when(response.getWriter()).thenReturn(writer);
+            when(response.getWriter()).thenReturn(writer);
         }
 
         static AssertStaplerResponse from(HttpResponse actual) throws IOException {
@@ -130,22 +130,22 @@ public class PrometheusActionTest {
         }
 
         private AssertStaplerResponse assertHttpStatus(int status) {
-            Mockito.verify(response).setStatus(status);
+            verify(response).setStatus(status);
             return this;
         }
 
         private AssertStaplerResponse assertContentType(String contentType) {
-            Mockito.verify(response).setContentType(contentType);
+            verify(response).setContentType(contentType);
             return this;
         }
 
         private AssertStaplerResponse assertHttpHeader(String name, String value) {
-            Mockito.verify(response).addHeader(name, value);
+            verify(response).addHeader(name, value);
             return this;
         }
 
         private AssertStaplerResponse assertBody(String payload) {
-            assertEquals(payload, stringWriter.toString());
+            assertThat(stringWriter.toString()).isEqualTo(payload);
             return this;
         }