Home > Enterprise >  How to mock class methods inside another class methods which we would like to implement unit test us
How to mock class methods inside another class methods which we would like to implement unit test us

Time:03-09

My code does 3 things in summary:

  • If-else block to check some conditions (I want to test only that part)
  • 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)

Here is my method which I would like to implement unit testing for if-else conditions:

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
  2. Appkiller is another class created to kill some application using put request if conditions are met

I tried to mock both of them and only test if-else conditions using test code below:

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
  2. yarnModel.checkYarnApplications() method returns some string according to conditions and I only would like to check if they are equal or not.

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. 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)

CodePudding user response:

I transferred mocks from @Before annotation to inside of the @Test annotation everything seems worked now. 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();
        }
    }
}
  • Related