简体   繁体   English

如何在我们想使用 Junit 和 Mockito 实现单元测试的另一个 class 方法中模拟 class 方法?

[英]How to mock class methods inside another class methods which we would like to implement unit test using Junit and Mockito?

My code does 3 things in summary:我的代码总结了三件事:

  • If-else block to check some conditions (I want to test only that part) If-else 块检查一些条件(我只想测试那部分)
  • Kill some application using put request (Which I want to mock and do not execute during unit test)使用放置请求杀死一些应用程序(我想模拟并且在单元测试期间不执行)
  • Create http connection to get Json string to check conditions (Which I want to mock and use pre-defined json object in assert method instead)创建 http 连接以获取 Json 字符串以检查条件(我想模拟并在断言方法中使用预定义的 json object 代替)

Here is my method which I would like to implement unit testing for if-else conditions:这是我想对 if-else 条件实施单元测试的方法:

public String checkYarnApplications() throws IOException {

    String infoMessage = null;

    ObjectGetter objectGetter = new ObjectGetter(getUrlAddress());

    JSONObject j = objectGetter.objectGetter();

    // Initialize stringbuilder to build slack message
    StringBuilder stringBuilder = new StringBuilder();

    // Iterate through number of existing yarn application
    for (int i = 0; i < j.getJSONObject("apps").getJSONArray("app").length(); i++){

        JSONObject name = j.getJSONObject("apps")
                .getJSONArray("app")
                .getJSONObject(i);

        String state = name.get("state").toString();

        // Check if application is in Running state
        if (state.equals("RUNNING")){

            // Get elapsed time for each running application and convert it to hour
            int elapsed_time = name.getInt("elapsedTime")/3600000;
            // Get application name
            String app_name = name.get("name").toString();
            // Get application queue_name
            String queue_name = name.get("queue").toString();
            // Get application user_name
            String user_name = name.get("user").toString();

            // Check if pyspark applications last longer than specified time in config.properties
            if (app_name.startsWith("pyspark-shell") && elapsed_time > getSparkCheckTime()){
                String app_id = name.get("id").toString();
                String infoMessageSpark = "pyspark application " + app_id + " has been killed because it takes longer than " +
                        getSparkCheckTime() + " hours. Elapsed Time:" + elapsed_time + " hours";
                infoMessage = infoMessageSpark;
                logger.info(infoMessageSpark);
                logger.info(name.toString());
                // Kill yarn application
                AppKiller appKiller = new AppKiller(String.format("%s%s/state?user.name=atlasapp",getUrlAddress(),app_id));
                appKiller.appKiller();
                // Add info message to slackmessage string builder
                stringBuilder.append(infoMessageSpark);
                stringBuilder.append("\n");
            }
            // Check if self_bi applications last longer than specified time in config.properties
            else if (!queue_name.equals("yarn-system") && !queue_name.equals("hudi") && !queue_name.equals("hepsistream") &&
                    !app_name.equals("Bzip2Hdfs") && !user_name.equals("spark") && !user_name.equals("yarn-ats") &&
                    !app_name.startsWith("pyspark-shell") && !queue_name.equals("llap") && elapsed_time > getappCheckTime()){
                String app_id = name.get("id").toString();
                String infoMessageSb = queue_name + " application, " + app_id + " has been killed because it takes longer than "
                        + getappCheckTime() + " hours. Elapsed Time:" + elapsed_time + " hours";
                infoMessage = infoMessageSb;
                logger.info(infoMessageSb);
                logger.info(name.toString());
                // Kill yarn application
                AppKiller appKiller = new AppKiller(String.format("%s%s/state?user.name=atlasapp",getUrlAddress(),app_id));
                appKiller.appKiller();
                // Add info message to slackmessage string builder
                stringBuilder.append(infoMessageSb);
                stringBuilder.append("\n");
            }
            // Check if any application except hudi, llap last longer than specified time in config.properties and send them to slack channel
            else if (!queue_name.equals("hudi") && !queue_name.equals("llap") && !queue_name.equals("hepsistream") &&
                    !queue_name.equals("yarn-system") && !user_name.equals("yarn-ats") &&
                    !app_name.startsWith("pyspark-shell") && !app_name.equals("Bzip2Hdfs") && !user_name.equals("spark") &&
                    elapsed_time > getCheckTime()){
                logger.info("Application_id: " + name.get("id").toString() + " is running longer than " +  getCheckTime() + " hours");
                String textMessage ="Elapsed time: " + elapsed_time + " hours" + ", " +
                        "Application_Id: " + name.get("id").toString() + ", " +
                        "Username: " + name.get("user").toString() + ", " +
                        "Queuename:" + name.get("queue").toString() + ", " +
                        "Usage:" + name.get("clusterUsagePercentage").toString();
                stringBuilder.append(textMessage);
                stringBuilder.append("\n");
            }
        }

    }
}

Some notes about the code:关于代码的一些说明:

  1. ObjectGetter is another class created to get Json object using http connection ObjectGetter 是另一个 class 创建,使用 http 连接获取 Json object
  2. Appkiller is another class created to kill some application using put request if conditions are met Appkiller 是另一个 class 创建的,用于在满足条件时使用 put 请求杀死某些应用程序

I tried to mock both of them and only test if-else conditions using test code below:我试图模拟它们,并且只使用下面的测试代码测试 if-else 条件:

class YarnModelTest {

private YarnModel yarnModel;
private static final ObjectGetter objectGetter = mock(ObjectGetter.class);
private static final AppKiller appKiller = mock(AppKiller.class);

@Before
public void setup() throws IOException {
    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    try (InputStream input = classloader.getResourceAsStream("config.properties")) {

        Properties properties = new Properties();

        // load a properties file
        properties.load(input);
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> map = mapper.readValue(properties.getProperty("jsonString"), Map.class);
        Scenerio scenerio = new Scenerio(map);
        when(objectGetter.objectGetter()).thenReturn((JSONObject) scenerio.getJsonObject());
        Mockito.doNothing().when(objectGetter).objectGetter();
        Mockito.doNothing().when(appKiller).appKiller();

    }
}

@Test
void checkSparkCheckTime() {
    YarnModel yarnModel = new YarnModel("http://localhost:8080", 24, 48, 24, "http://localhost:7070");
    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    try (InputStream input = classloader.getResourceAsStream("config.properties")) {

        Properties properties = new Properties();

        // load a properties file
        properties.load(input);
        String test = properties.getProperty("sparkTest");
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> map = mapper.readValue(properties.getProperty("jsonString"), Map.class);
        assertEquals(test, yarnModel.checkYarnApplications());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

} }

Some notes about test code:关于测试代码的一些说明:

  1. Properties using to get pre-defined json string form comparison in unit test用于在单元测试中获取预定义 json 字符串形式比较的属性
  2. yarnModel.checkYarnApplications() method returns some string according to conditions and I only would like to check if they are equal or not. yarnModel.checkYarnApplications() 方法根据条件返回一些字符串,我只想检查它们是否相等。

Problem:问题:

I am getting below error and as I understand from error my mocks are not correct and code still trying to create http connection.我遇到错误,据我所知,我的模拟不正确,代码仍在尝试创建 http 连接。 Any advice will be appreciated任何建议将被认真考虑

java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:607)
at java.net.Socket.connect(Socket.java:556)
at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
at sun.net.www.http.HttpClient.New(HttpClient.java:339)
at sun.net.www.http.HttpClient.New(HttpClient.java:357)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1223)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1162)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1056)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:990)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1567)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1495)
at java.net.URL.openStream(URL.java:1093)
at com.fasterxml.jackson.core.TokenStreamFactory._optimizedStreamFromURL(TokenStreamFactory.java:211)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1055)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3561)
at com.hepsiburada.Utils.ObjectGetter.objectGetter(ObjectGetter.java:33)
at com.hepsiburada.Model.YarnModel.checkYarnApplications(YarnModel.java:77)
at com.hepsiburada.Model.YarnModelTest.checkSparkCheckTime(YarnModelTest.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

I transferred mocks from @Before annotation to inside of the @Test annotation everything seems worked now.我将模拟从 @Before 注释转移到 @Test 注释内部,现在一切似乎都有效。 Below please find successfully developed test code:下面请看开发成功的测试代码:

    class YarnModelTest {

    private YarnModel yarnModel;
    private static final ObjectGetter objectGetter = mock(ObjectGetter.class);
    private static final AppKiller appKiller = mock(AppKiller.class);


    @Test
    void checkSparkCheckTime() {
        YarnModel yarnModel = new YarnModel("http://localhost:8088/ws/v1/cluster/apps/", 24, 48, 24, "http://localhost:7070");
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        try (InputStream input = classloader.getResourceAsStream("configuration.properties")) {

            Properties properties = new Properties();

            // load a properties file
            properties.load(input);
            String test = properties.getProperty("sparkTest");
            ObjectMapper mapper = new ObjectMapper();
            String json = properties.getProperty("jsonString");
            Map<String, Object> map = new HashMap<>();

            map = mapper.readValue(json, new TypeReference<Map<String, Object>>(){});
            JSONObject jsonobject = new JSONObject(map);

            when(objectGetter.objectGetter()).thenReturn(jsonobject);
            Mockito.doNothing().when(objectGetter).setUrlObjectString("http://atlasm03.infoshop.com.tr:8088/ws/v1/cluster/apps/");
            Mockito.doNothing().when(appKiller).appKiller();
            assertEquals(test,yarnModel.checkYarnApplications(objectGetter));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM