Home > Blockchain >  Unable to mock creating directory using mkdirs() calls in java void method
Unable to mock creating directory using mkdirs() calls in java void method

Time:06-19

While trying to run my test for the following code. I am getting some error detailed below.

I observed at the time it makes mkdirs() calls in my code throws IllegalArgumentException when I try to run my test.

MyClass.java

package com.javaeasily.demos.junit;

import java.util.ArrayList;

public class MyClass {
    private final NodeHelper nodeHelper;
    private static final ArrayList<String> ACTIVE_SERVICES_POST_RECONFIGURE = new ArrayList<>();

    // Only allow construction if number is greater than one
    MyClass() {
        ACTIVE_SERVICES_POST_RECONFIGURE.add("my-node-"   NodeUtils.getMyNode());
        nodeHelper = new NodeHelper();
    }

    public void reconfigureNode() {
        if (ACTIVE_SERVICES_POST_RECONFIGURE.isEmpty()) {
            return;
        }
        try {
            nodeHelper.createStagingDir();
        } catch (Exception e) {
            throw new RuntimeException("Cannot reconfigure node");
        }
    }
}


NodeUtils.java

package com.javaeasily.demos.junit;


import org.apache.commons.lang3.StringUtils;

public class NodeUtils {
    private static final String HOSTNAME_PREFIX = "my-node-";

    public static String hostnameToNode(String hostname) {
        if (!hostname.startsWith(HOSTNAME_PREFIX)) {
            throw new IllegalArgumentException(hostname   " is not recognized hostname");
        }
        return StringUtils.removeStart(hostname, HOSTNAME_PREFIX);
    }

    public static String getHostname() {
        return System.getenv("HOSTNAME");
    }

    public static String getMyNode() {
        return hostnameToNode(getHostname());
    }
}


NodeHelper.java

package com.javaeasily.demos.junit;

import java.io.File;

public class NodeHelper {
    private static final String STAGING_DIR = "/staging/";

    public void createStagingDir() {
        File stagingDir = new File(STAGING_DIR);
        if (!stagingDir.exists() && !stagingDir.mkdirs()) {
            throw new IllegalArgumentException("Could not create staging dir");
        }
    }
}

MyClassTest.java

package com.javaeasily.demos.junit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class MyClassTest {
    private MyClass myclass;

    @BeforeEach
    public void SetUp() {
        try (MockedStatic<NodeUtils> nodeUtilsMockedStatic = Mockito.mockStatic(NodeUtils.class);) {
            nodeUtilsMockedStatic.when(NodeUtils::getMyNode).thenReturn("foo");
            myclass = new MyClass();
        }
    }

    @Test
    public void testReconfigureNode() {
        myclass.reconfigureNode();
    }
}

When I try to run my test I get following error:

java.lang.RuntimeException: Cannot reconfigure node

    at com.javaeasily.demos.junit.MyClass.reconfigureNode(MyClass.java:22)

Post debugging I see that:

java.lang.IllegalArgumentException: Could not create staging dir

Does anyone care to enlighten me as to what I am doing wrong?

CodePudding user response:

To mock NodeHelper you should not create it inside MyClass, but inject it from the outside via the constructor. i.e.

MyClass(Nodehelper nodeHelper) {
    ACTIVE_SERVICES_POST_RECONFIGURE.add("my-node-"   NodeUtils.getMyNode());
    this.nodeHelper = nodeHelper;
}

This allows you to create a mocked NodeHelper in your test, pass it to MyClass and set the desired behavior as expectations.

  • Related