2

I have a piece of Java code which uses an environment variable. The behavior of the code depends on the value of environment variable. I would like to test this code using TestNG. I have some sample code for mock environmental variable using PowerMocikto.But, I got an exception. This is my unit test file:

import static org.testng.Assert.assertEquals;   
import org.powermock.api.mockito.PowerMockito;   
import org.powermock.core.classloader.annotations.PrepareForTest;   
import org.testng.IObjectFactory;   
import org.testng.annotations.BeforeClass;   
import org.testng.annotations.ObjectFactory;   
import org.testng.annotations.Test;    

@PrepareForTest(System.class)   
public class SampleTestClass {   
    @BeforeClass   
    public void setup() {   
        PowerMockito.mockStatic(System.class);  
        PowerMockito.when(System.getenv("hello")).thenReturn("world");  
    }

    @Test
    public void test() {
        assertEquals(System.getenv("hello"), "world");
    }

    @ObjectFactory
    public IObjectFactory getObjectFactory() {
        return new org.powermock.modules.testng.PowerMockObjectFactory();
    }

}

I got this exception

FAILED CONFIGURATION: @BeforeClass setup
org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class java.lang.System
Mockito cannot mock/spy because :
 - final class
    at powerMocito.SampleTestClass.setup(SampleTestClass.java:17)
    at powerMocito.SampleTestClass_$$_jvst6c2_0._d8setup(SampleTestClass_$$_jvst6c2_0.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.powermock.modules.testng.internal.PowerMockTestNGMethodHandler.invoke(PowerMockTestNGMethodHandler.java:50)
    at powerMocito.SampleTestClass_$$_jvst6c2_0.setup(SampleTestClass_$$_jvst6c2_0.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:514)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:215)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:178)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
    at org.testng.TestRunner.privateRun(TestRunner.java:782)
    at org.testng.TestRunner.run(TestRunner.java:632)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
    at org.testng.SuiteRunner.run(SuiteRunner.java:268)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
    at org.testng.TestNG.run(TestNG.java:1064)
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:113)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:206)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:177)

This is the dependencies in my pom file

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-testng</artifactId>
            <version>2.0.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.0-beta.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.27.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-support</artifactId>
            <version>2.0.0</version>
        </dependency>

Please help me to resolve this error. Is any other way to test this problem using TestNG ?

Ashish
  • 110
  • 4
  • 14
  • 1
    one option would be to write a wrapper for the system class that jsut passes system.getenv and mock that (youll obviously have to repalce all of the occurances of system.getenv in your code) I tihnk its a good idea to create a properties class anyways where you initialize all the system and Java variables at the start to reference if you implement it liek that you can alos easily mokc that properties class – jonathan Heindl Apr 20 '19 at 04:58
  • SystemRules may be an option. They are designed for JUnit 4, but it's a start. https://stackoverflow.com/questions/8168884/how-to-test-code-dependent-on-environment-variables-using-junit – Jens Dibbern Apr 20 '19 at 09:45

0 Answers0