Thursday 10 September 2015

How to mock static methods during unit testing?

Well, static mock is not implemented in Mockito, so we have to use PowerMock to achieve this:

Let's say we have the following class:

package com;

import
java.net.InetAddress;
import
java.net.UnknownHostException;

public final class
SystemUtils {

  
public static final String UNKNOWN_HOST = "Unknown";

   public static
String getHostName() {
      String hostname =
UNKNOWN_HOST;
      try
{
         InetAddress addr = InetAddress.getLocalHost()
;
        
// Get hostname
        
hostname = addr.getHostName();
     
} catch (UnknownHostException e ) {
         System.
out.println("catch UnknownHostException...");
     
}
     
return hostname;
  
}
}

and we need to test that UnknownHostException is thrown.
So our goal is to mock InetAddress.getLocalHost() and ask it to return an exception so SystemUtils.getHostName() will return 'Unknown'.

First import all needful libs:

<properties>

    <junit.version>4.11</junit.version>

    <mockito.version>1.10.19</mockito.version>

    <powermock.version>1.6.2</powermock.version>

</properties>



<dependency>
    <groupId>
junit</groupId>
    <artifactId>
junit</artifactId>
    <version>
${junit.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.mockito</groupId>
    <artifactId>
mockito-all</artifactId>
    <version>
${mockito.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.powermock</groupId>
    <artifactId>
powermock-api-mockito</artifactId>
    <version>
${powermock.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.powermock</groupId>
    <artifactId>
powermock-module-junit4</artifactId>
    <version>
${powermock.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.powermock</groupId>
    <artifactId>
powermock-module-junit4-rule</artifactId>
    <version>
${powermock.version}</version>
    <scope>
test</scope>
</dependency>

And test would look the following way:

import com.SystemUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.internal.stubbing.answers.ThrowsExceptionClass;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.net.InetAddress;
import java.net.UnknownHostException;
import static org.junit.Assert.assertEquals;


@RunWith(PowerMockRunner.class)
@PrepareForTest(SystemUtils.class)
public class SystemUtilsTest {

    @Test
    public void testGetHostName() throws UnknownHostException {
        PowerMockito.mockStatic(InetAddress.class);
        PowerMockito.when(InetAddress.getLocalHost())
                .then(new ThrowsExceptionClass(UnknownHostException.class));
        String actualValue = SystemUtils.getHostName();
        assertEquals("On exception expected unknown value", SystemUtils.UNKNOWN_HOST, actualValue);
    }
}

How to set log file with custom name in log4j2?

Sometimes having log4j2.xml file with default naming can be a problem if several projects share the same classpath. In order to change logger file at runtime the below method can be used:


public static void logAppInfo(String configFileName) {
    URL fileUrl = SLF4JHello.class.getClassLoader().getResource(configFileName);
    if (fileUrl == null) {
        throw new RuntimeException("File not found: " + configFileName);
    }
    try {
    LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
    loggerContext.setConfigLocation(fileUrl.toURI());
    loggerContext.updateLoggers();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
}

How to enable smart import in Intellij Idea 14?

To enable auto-import and auto optimize imports go to:

Intellij Idea 14 -> Settings -> Editor -> General -> Auto Import

and check two options:

1. Optimize import on the fly
2. Add unambiguous imports on the fly