You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ch...@apache.org on 2022/09/20 01:48:15 UTC

[dolphinscheduler] branch dev updated: [Improvement][Test] Give an example on replacing Powermock with Mockito (#11588)

This is an automated email from the ASF dual-hosted git repository.

chufenggao pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new e1b55db72a [Improvement][Test] Give an example on replacing Powermock with Mockito (#11588)
e1b55db72a is described below

commit e1b55db72ad14ac8372c495a6b1398d686f02365
Author: Eric Gao <er...@gmail.com>
AuthorDate: Tue Sep 20 09:48:02 2022 +0800

    [Improvement][Test] Give an example on replacing Powermock with Mockito (#11588)
    
    * Give an example on replacing powermock with mockito
    
    * Remove redundant comments
    
    * Refactoring related UTs for better readability.
---
 .../plugin/task/jupyter/JupyterParameters.java     |  52 ++----
 .../plugin/task/jupyter/JupyterTask.java           |  40 +----
 .../plugin/task/jupyter/JupyterTaskTest.java       | 181 ++++++++++-----------
 .../dolphinscheduler-task-zeppelin/pom.xml         |   7 +-
 .../plugin/task/zeppelin/ZeppelinTask.java         |   2 +-
 .../plugin/task/zeppelin/ZeppelinTaskTest.java     |  67 +++-----
 dolphinscheduler-task-plugin/pom.xml               |  10 ++
 7 files changed, 143 insertions(+), 216 deletions(-)

diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterParameters.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterParameters.java
index dd38049492..caf28f699f 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterParameters.java
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterParameters.java
@@ -17,70 +17,38 @@
 
 package org.apache.dolphinscheduler.plugin.task.jupyter;
 
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
 import org.apache.dolphinscheduler.plugin.task.api.model.ResourceInfo;
 import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
 
 import java.util.List;
 
-/**
- * jupyter parameters
- */
-@Getter
-@Setter
-@ToString
+import lombok.Data;
+
+@Data
 public class JupyterParameters extends AbstractParameters {
 
-    /**
-     * conda env name
-     */
     private String condaEnvName;
 
-    /**
-     * input note path
-     */
     private String inputNotePath;
 
-    /**
-     * output note path
-     */
     private String outputNotePath;
 
-    /**
-     * parameters to pass into jupyter note cells
-     */
+    // parameters to pass into jupyter note cells
     private String parameters;
 
-    /**
-     * jupyter kernel
-     */
     private String kernel;
 
-    /**
-     * the execution engine name to use in evaluating the notebook
-     */
+    // the execution engine name to use in evaluating the notebook
     private String engine;
 
-    /**
-     * time in seconds to wait for each cell before failing execution (default: forever)
-     */
+    // time in seconds to wait for each cell before failing execution (default: forever)
     private String executionTimeout;
 
-    /**
-     * time in seconds to wait for kernel to start
-     */
+    // time in seconds to wait for kernel to start
     private String startTimeout;
 
-    /**
-     * other arguments
-     */
     private String others;
-
-    /**
-     * resource list
-     */
     private List<ResourceInfo> resourceList;
 
     @Override
@@ -90,7 +58,9 @@ public class JupyterParameters extends AbstractParameters {
 
     @Override
     public boolean checkParameters() {
-        return condaEnvName != null && inputNotePath != null && outputNotePath != null;
+        return StringUtils.isNotEmpty(condaEnvName) &&
+                StringUtils.isNotEmpty(inputNotePath) &&
+                StringUtils.isNotEmpty(outputNotePath);
     }
 
 }
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTask.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTask.java
index a83f4081ff..a1b9ec430f 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTask.java
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/main/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTask.java
@@ -43,14 +43,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 
 public class JupyterTask extends AbstractRemoteTask {
 
-    /**
-     * jupyter parameters
-     */
     private JupyterParameters jupyterParameters;
 
-    /**
-     * taskExecutionContext
-     */
     private TaskExecutionContext taskExecutionContext;
 
     private ShellCommandExecutor shellCommandExecutor;
@@ -88,7 +82,6 @@ public class JupyterTask extends AbstractRemoteTask {
     @Override
     public void handle(TaskCallBack taskCallBack) throws TaskException {
         try {
-            // SHELL task exit code
             TaskResponse response = shellCommandExecutor.run(buildCommand());
             setExitStatusCode(response.getExitStatusCode());
             setAppIds(String.join(TaskConstants.COMMA, getApplicationIds()));
@@ -116,16 +109,12 @@ public class JupyterTask extends AbstractRemoteTask {
     }
 
     /**
-     * create command
-     *
-     * @return command
+     * command will be like: papermill [OPTIONS] NOTEBOOK_PATH [OUTPUT_PATH]
      */
     protected String buildCommand() throws IOException {
-        /**
-         * papermill [OPTIONS] NOTEBOOK_PATH [OUTPUT_PATH]
-         */
+
         List<String> args = new ArrayList<>();
-        final String condaPath = PropertyUtils.getString(TaskConstants.CONDA_PATH);
+        final String condaPath = readCondaPath();
         final String timestamp = DateUtils.getTimestampString();
         String condaEnvName = jupyterParameters.getCondaEnvName();
         if (condaEnvName.endsWith(JupyterConstants.TXT_SUFFIX)) {
@@ -149,11 +138,7 @@ public class JupyterTask extends AbstractRemoteTask {
         args.add(JupyterConstants.PAPERMILL);
         args.add(jupyterParameters.getInputNotePath());
         args.add(jupyterParameters.getOutputNotePath());
-
-        // populate jupyter parameterization
         args.addAll(populateJupyterParameterization());
-
-        // populate jupyter options
         args.addAll(populateJupyterOptions());
 
         // remove tmp conda env, if created from requirements.txt
@@ -164,7 +149,6 @@ public class JupyterTask extends AbstractRemoteTask {
 
         // replace placeholder, and combining local and global parameters
         Map<String, Property> paramsMap = taskExecutionContext.getPrepareParamsMap();
-
         String command = ParameterUtils
                 .convertParameterPlaceholders(String.join(" ", args), ParamUtils.convert(paramsMap));
 
@@ -173,12 +157,11 @@ public class JupyterTask extends AbstractRemoteTask {
         return command;
     }
 
-    /**
-     * build jupyter parameterization
-     *
-     * @return argument list
-     */
-    private List<String> populateJupyterParameterization() throws IOException {
+    protected String readCondaPath() {
+        return PropertyUtils.getString(TaskConstants.CONDA_PATH);
+    }
+
+    protected List<String> populateJupyterParameterization() throws IOException {
         List<String> args = new ArrayList<>();
         String parameters = jupyterParameters.getParameters();
         if (StringUtils.isNotEmpty(parameters)) {
@@ -200,12 +183,7 @@ public class JupyterTask extends AbstractRemoteTask {
         return args;
     }
 
-    /**
-     * build jupyter options
-     *
-     * @return argument list
-     */
-    private List<String> populateJupyterOptions() {
+    protected List<String> populateJupyterOptions() {
         List<String> args = new ArrayList<>();
         String kernel = jupyterParameters.getKernel();
         if (StringUtils.isNotEmpty(kernel)) {
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/test/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTaskTest.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/test/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTaskTest.java
index 3007a4ee25..1fe03b9640 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/test/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTaskTest.java
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-jupyter/src/test/java/org/apache/dolphinscheduler/plugin/task/jupyter/JupyterTaskTest.java
@@ -17,121 +17,112 @@
 
 package org.apache.dolphinscheduler.plugin.task.jupyter;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
 import org.apache.dolphinscheduler.spi.utils.DateUtils;
 import org.apache.dolphinscheduler.spi.utils.JSONUtils;
-import org.apache.dolphinscheduler.spi.utils.PropertyUtils;
+
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
-import org.powermock.modules.junit4.PowerMockRunner;
-import static org.mockito.ArgumentMatchers.any;
-import static org.powermock.api.mockito.PowerMockito.spy;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({
-        JSONUtils.class,
-        PropertyUtils.class,
-        DateUtils.class
-})
-@PowerMockIgnore({"javax.*"})
-@SuppressStaticInitializationFor("org.apache.dolphinscheduler.spi.utils.PropertyUtils")
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
 public class JupyterTaskTest {
 
+    private static final String EXPECTED_JUPYTER_TASK_COMMAND_USE_LOCAL_CONDA_ENV =
+            "source /opt/anaconda3/etc/profile.d/conda.sh && " +
+                    "conda activate jupyter-lab && " +
+                    "papermill " +
+                    "/test/input_note.ipynb " +
+                    "/test/output_note.ipynb " +
+                    "--parameters city Shanghai " +
+                    "--parameters factor 0.01 " +
+                    "--kernel python3 " +
+                    "--engine default_engine " +
+                    "--execution-timeout 10 " +
+                    "--start-timeout 3 " +
+                    "--version " +
+                    "--inject-paths " +
+                    "--progress-bar";
+
+    private static final String EXPECTED_JUPYTER_TASK_COMMAND_USE_PACKED_CONDA_ENV =
+            "source /opt/anaconda3/etc/profile.d/conda.sh && " +
+                    "mkdir jupyter_env && " +
+                    "tar -xzf jupyter.tar.gz -C jupyter_env && " +
+                    "source jupyter_env/bin/activate && " +
+                    "papermill " +
+                    "/test/input_note.ipynb " +
+                    "/test/output_note.ipynb " +
+                    "--parameters city Shanghai " +
+                    "--parameters factor 0.01 " +
+                    "--kernel python3 " +
+                    "--engine default_engine " +
+                    "--execution-timeout 10 " +
+                    "--start-timeout 3 " +
+                    "--version " +
+                    "--inject-paths " +
+                    "--progress-bar";
+
+    private static final String EXPECTED_JUPYTER_TASK_COMMAND_USE_PIP_REQUIREMENTS =
+            "set +e \n " +
+                    "source /opt/anaconda3/etc/profile.d/conda.sh && " +
+                    "conda create -n jupyter-tmp-env-123456789 -y && " +
+                    "conda activate jupyter-tmp-env-123456789 && " +
+                    "pip install -r requirements.txt && " +
+                    "papermill " +
+                    "/test/input_note.ipynb " +
+                    "/test/output_note.ipynb " +
+                    "--parameters city Shanghai " +
+                    "--parameters factor 0.01 " +
+                    "--kernel python3 " +
+                    "--engine default_engine " +
+                    "--execution-timeout 10 " +
+                    "--start-timeout 3 " +
+                    "--version " +
+                    "--inject-paths " +
+                    "--progress-bar \n " +
+                    "conda deactivate && conda remove --name jupyter-tmp-env-123456789 --all -y";
+
     @Test
-    public void testBuildJupyterCommandWithLocalEnv() throws Exception {
-        String parameters = buildJupyterCommandWithLocalEnv();
-        TaskExecutionContext taskExecutionContext = PowerMockito.mock(TaskExecutionContext.class);
-        when(taskExecutionContext.getTaskParams()).thenReturn(parameters);
-        PowerMockito.mockStatic(PropertyUtils.class);
-        when(PropertyUtils.getString(any())).thenReturn("/opt/anaconda3/etc/profile.d/conda.sh");
-        JupyterTask jupyterTask = spy(new JupyterTask(taskExecutionContext));
+    public void jupyterTaskUseLocalCondaEnv() throws Exception {
+        String jupyterTaskParameters = buildJupyterTaskUseLocalCondaEnvCommand();
+        JupyterTask jupyterTask = prepareJupyterTaskForTest(jupyterTaskParameters);
         jupyterTask.init();
-        Assert.assertEquals(jupyterTask.buildCommand(),
-            "source /opt/anaconda3/etc/profile.d/conda.sh && " +
-                "conda activate jupyter-lab && " +
-                "papermill " +
-                "/test/input_note.ipynb " +
-                "/test/output_note.ipynb " +
-                "--parameters city Shanghai " +
-                "--parameters factor 0.01 " +
-                "--kernel python3 " +
-                "--engine default_engine " +
-                "--execution-timeout 10 " +
-                "--start-timeout 3 " +
-                "--version " +
-                "--inject-paths " +
-                "--progress-bar");
+        Assert.assertEquals(jupyterTask.buildCommand(), EXPECTED_JUPYTER_TASK_COMMAND_USE_LOCAL_CONDA_ENV);
     }
 
     @Test
-    public void testBuildJupyterCommandWithPackedEnv() throws Exception {
-        String parameters = buildJupyterCommandWithPackedEnv();
-        TaskExecutionContext taskExecutionContext = PowerMockito.mock(TaskExecutionContext.class);
-        when(taskExecutionContext.getTaskParams()).thenReturn(parameters);
-        PowerMockito.mockStatic(PropertyUtils.class);
-        when(PropertyUtils.getString(any())).thenReturn("/opt/anaconda3/etc/profile.d/conda.sh");
-        JupyterTask jupyterTask = spy(new JupyterTask(taskExecutionContext));
+    public void jupyterTaskUsePackedCondaEnv() throws Exception {
+        String jupyterTaskParameters = buildJupyterTaskUsePackedCondaEnvCommand();
+        JupyterTask jupyterTask = prepareJupyterTaskForTest(jupyterTaskParameters);
         jupyterTask.init();
-        Assert.assertEquals(jupyterTask.buildCommand(),
-                "source /opt/anaconda3/etc/profile.d/conda.sh && " +
-                        "mkdir jupyter_env && " +
-                        "tar -xzf jupyter.tar.gz -C jupyter_env && " +
-                        "source jupyter_env/bin/activate && " +
-                        "papermill " +
-                        "/test/input_note.ipynb " +
-                        "/test/output_note.ipynb " +
-                        "--parameters city Shanghai " +
-                        "--parameters factor 0.01 " +
-                        "--kernel python3 " +
-                        "--engine default_engine " +
-                        "--execution-timeout 10 " +
-                        "--start-timeout 3 " +
-                        "--version " +
-                        "--inject-paths " +
-                        "--progress-bar");
+        Assert.assertEquals(jupyterTask.buildCommand(), EXPECTED_JUPYTER_TASK_COMMAND_USE_PACKED_CONDA_ENV);
     }
 
     @Test
-    public void testBuildJupyterCommandWithRequirements() throws Exception {
-        String parameters = buildJupyterCommandWithRequirements();
-        TaskExecutionContext taskExecutionContext = PowerMockito.mock(TaskExecutionContext.class);
-        when(taskExecutionContext.getTaskParams()).thenReturn(parameters);
-        PowerMockito.mockStatic(PropertyUtils.class);
-        when(PropertyUtils.getString(any())).thenReturn("/opt/anaconda3/etc/profile.d/conda.sh");
-        PowerMockito.mockStatic(DateUtils.class);
+    public void jupyterTaskUsePipRequirements() throws Exception {
+        String jupyterTaskParameters = buildJupyterTaskUsePipRequirementsCommand();
+        JupyterTask jupyterTask = prepareJupyterTaskForTest(jupyterTaskParameters);
+        Mockito.mockStatic(DateUtils.class);
         when(DateUtils.getTimestampString()).thenReturn("123456789");
-        JupyterTask jupyterTask = spy(new JupyterTask(taskExecutionContext));
         jupyterTask.init();
-        Assert.assertEquals(jupyterTask.buildCommand(),
-                "set +e \n " +
-                        "source /opt/anaconda3/etc/profile.d/conda.sh && " +
-                        "conda create -n jupyter-tmp-env-123456789 -y && " +
-                        "conda activate jupyter-tmp-env-123456789 && " +
-                        "pip install -r requirements.txt && " +
-                        "papermill " +
-                        "/test/input_note.ipynb " +
-                        "/test/output_note.ipynb " +
-                        "--parameters city Shanghai " +
-                        "--parameters factor 0.01 " +
-                        "--kernel python3 " +
-                        "--engine default_engine " +
-                        "--execution-timeout 10 " +
-                        "--start-timeout 3 " +
-                        "--version " +
-                        "--inject-paths " +
-                        "--progress-bar \n " +
-                        "conda deactivate && conda remove --name jupyter-tmp-env-123456789 --all -y"
-                );
+        Assert.assertEquals(jupyterTask.buildCommand(), EXPECTED_JUPYTER_TASK_COMMAND_USE_PIP_REQUIREMENTS);
+    }
+
+    private JupyterTask prepareJupyterTaskForTest(final String jupyterTaskParameters) {
+        TaskExecutionContext taskExecutionContext = Mockito.mock(TaskExecutionContext.class);
+        when(taskExecutionContext.getTaskParams()).thenReturn(jupyterTaskParameters);
+        JupyterTask jupyterTask = spy(new JupyterTask(taskExecutionContext));
+        doReturn("/opt/anaconda3/etc/profile.d/conda.sh").when(jupyterTask).readCondaPath();
+        return jupyterTask;
     }
 
-    private String buildJupyterCommandWithLocalEnv() {
+    private String buildJupyterTaskUseLocalCondaEnvCommand() {
         JupyterParameters jupyterParameters = new JupyterParameters();
         jupyterParameters.setCondaEnvName("jupyter-lab");
         jupyterParameters.setInputNotePath("/test/input_note.ipynb");
@@ -145,7 +136,7 @@ public class JupyterTaskTest {
         return JSONUtils.toJsonString(jupyterParameters);
     }
 
-    private String buildJupyterCommandWithPackedEnv() {
+    private String buildJupyterTaskUsePackedCondaEnvCommand() {
         JupyterParameters jupyterParameters = new JupyterParameters();
         jupyterParameters.setCondaEnvName("jupyter.tar.gz");
         jupyterParameters.setInputNotePath("/test/input_note.ipynb");
@@ -159,7 +150,7 @@ public class JupyterTaskTest {
         return JSONUtils.toJsonString(jupyterParameters);
     }
 
-    private String buildJupyterCommandWithRequirements() {
+    private String buildJupyterTaskUsePipRequirementsCommand() {
         JupyterParameters jupyterParameters = new JupyterParameters();
         jupyterParameters.setCondaEnvName("requirements.txt");
         jupyterParameters.setInputNotePath("/test/input_note.ipynb");
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/pom.xml b/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/pom.xml
index 4ae533bcc1..69a5a66994 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/pom.xml
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/pom.xml
@@ -15,15 +15,14 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
     <parent>
-        <artifactId>dolphinscheduler-task-plugin</artifactId>
         <groupId>org.apache.dolphinscheduler</groupId>
+        <artifactId>dolphinscheduler-task-plugin</artifactId>
         <version>dev-SNAPSHOT</version>
     </parent>
-    <modelVersion>4.0.0</modelVersion>
     <artifactId>dolphinscheduler-task-zeppelin</artifactId>
     <packaging>jar</packaging>
 
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/main/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTask.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/main/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTask.java
index 5c0473154e..7fc0f09adb 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/main/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTask.java
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/main/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTask.java
@@ -165,7 +165,7 @@ public class ZeppelinTask extends AbstractRemoteTask {
      *
      * @return ZeppelinClient
      */
-    private ZeppelinClient getZeppelinClient() {
+    protected ZeppelinClient getZeppelinClient() {
         final String restEndpoint = zeppelinParameters.getRestEndpoint();
         final ClientConfig clientConfig = new ClientConfig(restEndpoint);
         ZeppelinClient zClient = null;
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/test/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTaskTest.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/test/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTaskTest.java
index 70a0945a94..b33b4d43ff 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/test/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTaskTest.java
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-zeppelin/src/test/java/org/apache/dolphinscheduler/plugin/task/zeppelin/ZeppelinTaskTest.java
@@ -20,14 +20,11 @@ package org.apache.dolphinscheduler.plugin.task.zeppelin;
 import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.EXIT_CODE_FAILURE;
 import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.EXIT_CODE_KILL;
 import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.EXIT_CODE_SUCCESS;
-
 import static org.mockito.ArgumentMatchers.any;
-import static org.powermock.api.mockito.PowerMockito.doReturn;
-import static org.powermock.api.mockito.PowerMockito.mock;
-import static org.powermock.api.mockito.PowerMockito.spy;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import org.apache.dolphinscheduler.plugin.task.api.TaskCallBack;
 import org.apache.dolphinscheduler.plugin.task.api.TaskException;
@@ -35,32 +32,23 @@ import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
 import org.apache.dolphinscheduler.spi.utils.DateUtils;
 import org.apache.dolphinscheduler.spi.utils.JSONUtils;
 
-
-import org.apache.zeppelin.client.ParagraphResult;
 import org.apache.zeppelin.client.NoteResult;
+import org.apache.zeppelin.client.ParagraphResult;
 import org.apache.zeppelin.client.Status;
 import org.apache.zeppelin.client.ZeppelinClient;
+
+import java.util.Map;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 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 java.util.Map;
+import org.mockito.junit.MockitoJUnitRunner;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({
-    ZeppelinTask.class,
-    ZeppelinClient.class,
-    ObjectMapper.class,
-    DateUtils.class
-})
-@PowerMockIgnore({"javax.*"})
+@RunWith(MockitoJUnitRunner.class)
 public class ZeppelinTaskTest {
 
     private static final String MOCK_NOTE_ID = "2GYJR92R7";
@@ -82,16 +70,14 @@ public class ZeppelinTaskTest {
     @Before
     public void before() throws Exception {
         String zeppelinParameters = buildZeppelinTaskParameters();
-        TaskExecutionContext taskExecutionContext = PowerMockito.mock(TaskExecutionContext.class);
+        TaskExecutionContext taskExecutionContext = mock(TaskExecutionContext.class);
         when(taskExecutionContext.getTaskParams()).thenReturn(zeppelinParameters);
         this.zeppelinTask = spy(new ZeppelinTask(taskExecutionContext));
 
-        // mock zClient and paragraph result
         this.zClient = mock(ZeppelinClient.class);
         this.paragraphResult = mock(ParagraphResult.class);
 
-        // use mocked zClient in zeppelinTask
-        doReturn(this.zClient).when(this.zeppelinTask, "getZeppelinClient");
+        doReturn(this.zClient).when(this.zeppelinTask).getZeppelinClient();
         when(this.zClient.executeParagraph(any(), any(), any(Map.class))).thenReturn(this.paragraphResult);
         when(paragraphResult.getResultInText()).thenReturn("mock-zeppelin-paragraph-execution-result");
         this.zeppelinTask.init();
@@ -135,10 +121,10 @@ public class ZeppelinTaskTest {
 
     @Test(expected = TaskException.class)
     public void testHandleWithParagraphExecutionException() throws Exception {
-        when(this.zClient.executeParagraph(any(), any(), any(Map.class))).
-                thenThrow(new TaskException("Something wrong happens from zeppelin side"));
-//        when(this.paragraphResult.getStatus()).thenReturn(Status.ERROR);
+        when(this.zClient.executeParagraph(any(), any(), any(Map.class)))
+                .thenThrow(new TaskException("Something wrong happens from zeppelin side"));
         this.zeppelinTask.handle(taskCallBack);
+
         Mockito.verify(this.zClient).executeParagraph(MOCK_NOTE_ID,
                 MOCK_PARAGRAPH_ID,
                 (Map<String, String>) mapper.readValue(MOCK_PARAMETERS, Map.class));
@@ -150,21 +136,18 @@ public class ZeppelinTaskTest {
     @Test
     public void testHandleWithNoteExecutionSuccess() throws Exception {
         String zeppelinParametersWithNoParagraphId = buildZeppelinTaskParametersWithNoParagraphId();
-        TaskExecutionContext taskExecutionContext= PowerMockito.mock(TaskExecutionContext.class);
+        TaskExecutionContext taskExecutionContext = mock(TaskExecutionContext.class);
         when(taskExecutionContext.getTaskParams()).thenReturn(zeppelinParametersWithNoParagraphId);
         this.zeppelinTask = spy(new ZeppelinTask(taskExecutionContext));
 
-        // mock zClient and note result
         this.zClient = mock(ZeppelinClient.class);
         this.noteResult = mock(NoteResult.class);
 
-        // use mocked zClient in zeppelinTask
-        doReturn(this.zClient).when(this.zeppelinTask, "getZeppelinClient");
+        doReturn(this.zClient).when(this.zeppelinTask).getZeppelinClient();
         when(this.zClient.executeNote(any(), any(Map.class))).thenReturn(this.noteResult);
-        when(paragraphResult.getResultInText()).thenReturn("mock-zeppelin-paragraph-execution-result");
         this.zeppelinTask.init();
-        when(this.paragraphResult.getStatus()).thenReturn(Status.FINISHED);
         this.zeppelinTask.handle(taskCallBack);
+
         Mockito.verify(this.zClient).executeNote(MOCK_NOTE_ID,
                 (Map<String, String>) mapper.readValue(MOCK_PARAMETERS, Map.class));
         Mockito.verify(this.noteResult).getParagraphResultList();
@@ -174,22 +157,18 @@ public class ZeppelinTaskTest {
     @Test
     public void testHandleWithNoteExecutionSuccessWithProductionSetting() throws Exception {
         String zeppelinParametersWithNoParagraphId = buildZeppelinTaskParametersWithProductionSetting();
-        TaskExecutionContext taskExecutionContext = PowerMockito.mock(TaskExecutionContext.class);
-        PowerMockito.mockStatic(DateUtils.class);
+        TaskExecutionContext taskExecutionContext = mock(TaskExecutionContext.class);
+        Mockito.mockStatic(DateUtils.class);
         when(taskExecutionContext.getTaskParams()).thenReturn(zeppelinParametersWithNoParagraphId);
         this.zeppelinTask = spy(new ZeppelinTask(taskExecutionContext));
 
-        // mock zClient and note result
         this.zClient = mock(ZeppelinClient.class);
         this.noteResult = mock(NoteResult.class);
 
-        // use mocked zClient in zeppelinTask
-        doReturn(this.zClient).when(this.zeppelinTask, "getZeppelinClient");
+        doReturn(this.zClient).when(this.zeppelinTask).getZeppelinClient();
         when(this.zClient.cloneNote(any(String.class), any(String.class))).thenReturn(MOCK_CLONE_NOTE_ID);
         when(this.zClient.executeNote(any(), any(Map.class))).thenReturn(this.noteResult);
-        when(paragraphResult.getResultInText()).thenReturn("mock-zeppelin-paragraph-execution-result");
         this.zeppelinTask.init();
-        when(this.paragraphResult.getStatus()).thenReturn(Status.FINISHED);
         when(DateUtils.getTimestampString()).thenReturn("123456789");
         this.zeppelinTask.handle(taskCallBack);
         Mockito.verify(this.zClient).cloneNote(
@@ -231,4 +210,4 @@ public class ZeppelinTaskTest {
         return JSONUtils.toJsonString(zeppelinParameters);
     }
 
-}
\ No newline at end of file
+}
diff --git a/dolphinscheduler-task-plugin/pom.xml b/dolphinscheduler-task-plugin/pom.xml
index 744a285826..b5e5c06572 100644
--- a/dolphinscheduler-task-plugin/pom.xml
+++ b/dolphinscheduler-task-plugin/pom.xml
@@ -75,4 +75,14 @@
             </dependency>
         </dependencies>
     </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-inline</artifactId>
+            <version>3.12.4</version>
+            <!-- TODO: move this dependency to root pom after removing powermock in the whole project -->
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>