Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock private static final field using mockito or Jmockit

I am using private static final LOGGER field in my class and I want LOGGER.isInfoEnabled() method to return false. How can I mock the static final field by using mockito or jMockit

My class is:

  import org.slf4j.Logger;   import org.slf4j.LoggerFactory;    public class Class1 {    private static final Logger LOGGER = LoggerFactory.getLogger(Class1.class);      public boolean demoMethod() {        System.out.println("Demo started");        if (LOGGER.isInfoEnabled()) {          System.out.println("@@@@@@@@@@@@@@ ------- info is enabled");        } else {          System.out.println("info is disabled");        }        return LOGGER.isInfoEnabled();     }   } 

and its junit is :

import mockit.Mocked; import mockit.NonStrictExpectations; import org.mockito.InjectMocks; import org.mockito.MockitoAnnotations; import org.slf4j.Logger; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;  import static org.testng.Assert.*; import com.source.Class1;  public class MyTest {    @InjectMocks   Class1 cls1;    @BeforeMethod   public void initMocks() {     MockitoAnnotations.initMocks(this);   }    @Test   public void test(@Mocked final Logger LOGGER) {      new NonStrictExpectations() {       {         LOGGER.isInfoEnabled();         result = false;       }     };     assertFalse(cls1.demoMethod());   } } 

when I run it the result is:

-------------------------------------------------------  T E S T S ------------------------------------------------------- Running com.test.MyTest Configuring TestNG with: TestNG652Configurator Demo started @@@@@@@@@@@@@@ ------- info is enabled Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.9 sec <<< FAILURE! - in com.test.MyTest test(com.test.MyTest)  Time elapsed: 0.168 sec  <<< FAILURE! java.lang.AssertionError: expected [false] but found [true]         at com.test.MyTest.test(MyTest.java:35)   Results :  Failed tests:   MyTest.test:35 expected [false] but found [true]  Tests run: 1, Failures: 1, Errors: 0, Skipped: 0  [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.899s [INFO] Finished at: Mon Jun 08 12:35:36 IST 2015 [INFO] Final Memory: 16M/166M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project JMockDemo: The re are test failures. [ERROR] [ERROR] Please refer to D:\perfoce_code\workspace_kepler\JMockDemo\target\surefire-reports for the individual test results. [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException 

I am new to jmockit and I want my above junit case to run successfully. And I have to use JMockit or mockito, can't use Powermockito. Please help.

like image 690
RaT Avatar asked Jun 08 '15 07:06

RaT


People also ask

Can we mock private methods using Mockito?

For Mockito, there is no direct support to mock private and static methods. In order to test private methods, you will need to refactor the code to change the access to protected (or package) and you will have to avoid static/final methods.

Can we mock static methods with Mockito?

Since static method belongs to the class, there is no way in Mockito to mock static methods.

Which Mockito framework is used to mock the static method?

As previously mentioned, since Mockito 3.4. 0, we can use the Mockito. mockStatic(Class<T> classToMock) method to mock invocations to static method calls. This method returns a MockedStatic object for our type, which is a scoped mock object.


1 Answers

One way is using reflection get rid of final modifier from the field and then replace the LOGGER field with Mocked one

public class Class1Test {     @Test     public void test() throws Exception {         Logger logger = Mockito.mock(Logger.class);         Mockito.when(logger.isInfoEnabled()).thenReturn(false);         setFinalStatic(Class1.class.getDeclaredField("LOGGER"), logger);         Class1 cls1 = new Class1();         assertFalse(cls1.demoMethod());     }      static void setFinalStatic(Field field, Object newValue) throws Exception {         field.setAccessible(true);                 Field modifiersField = Field.class.getDeclaredField("modifiers");         modifiersField.setAccessible(true);         modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);         field.set(null, newValue);     } } 
like image 67
Nitin Dandriyal Avatar answered Sep 28 '22 04:09

Nitin Dandriyal