Search code examples
javajunitmockitopowermockito

Mocking static method using power mockito


I hava a class Engine.class

with static function

public static  HashMap<String, String> loadLanguageCodeFile(HashMap<String,String> hash_map) {
    SystemSettings settings;
    FileReader fr = null;
    BufferedReader br = null;
    try {
      settings = SystemSettings.GetInstance();
      String path = settings.getLangCodePath();
      fr = new FileReader(path + FILENAME);
      br = new BufferedReader(fr);
      String Line;
      while ((Line = br.readLine())!= null) {
        String[] lang_codes =  Line.split("\\s+");
        hash_map.put(lang_codes[0], lang_codes[1]);
      }
    } catch (IOException e) {
      log.error("MicrosoftEngine: Unable to load file.", e);
    } catch (WorldlingoException e){
      log.error("MicrosoftEngine:", e);
    }
    finally {
      try {
        if (fr != null) {
          fr.close();
        }
        if (br != null) {
          br.close();
        }
      } catch ( IOException e) {
        log.error("MicrosoftEngine : An error occured while closing a resource.", e);
      }
    }
   return hash_map;
  }

I am trying to write a test case for this method. Systemsetting is another class and

settings = SystemSettings.GetInstance();
      String path = settings.getLangCodePath();

` gives the instance of another class and contains path file like \var\log file in path .

I am trying to write a test case using mockito. Since it is an static class, I used powermockito.

@RunWith(PowerMockRunner.class)
@PrepareForTest({HttpClientBuilder.class,Engine.class, SystemSettings.class})

 public class EngineTest extends TestCase {

        public void testLoadLanguageCodeFile() throws Exception {
            PowerMockito.mockStatic(Engine.class);
            PowerMockito.mockStatic(SystemSettings.class);
            MicrosoftEngine MSmock = Mockito.mock(Engine.class);
            SystemSettings SystemSettingsMock = Mockito.mock(SystemSettings.class);
            Mockito.when(SystemSettingsMock.GetInstance()).thenReturn(SystemSettingsMock);
            HashMap<String, String> hash_map = new HashMap<String, String>();
            MSmock.loadLanguageCodeFile(hash_map);
    }

I am not able to call the above loadLanguageCodeFile method. Any suggestion how to call static method will be appreciated


Solution

  • You are not suppose to mock the subject under test. You mock the dependencies of the subject under test that are needed to exercise the test to completion.

    The code is also tightly coupled to implementation concerns like the file reader and buffer reader.

    However as indicated in the comments you want to test the actual reading of a file at the path provided by the mocked settings.

    In that case you only need to mock SystemSettings and should call the actual member under test

    RunWith(PowerMockRunner.class)
    @PrepareForTest({SystemSettings.class})
    public class EngineTest extends TestCase {
        public void testLoadLanguageCodeFile() throws Exception {
            //Arrange
            String path = "Path to test file to be read";
            PowerMockito.mockStatic(SystemSettings.class);
            //instance mock
            SystemSettings settings = Mockito.mock(SystemSettings.class);
            Mockito.when(settings.getLangCodePath()).thenReturn(path);
            //mock static call
            Mockito.when(SystemSettings.GetInstance()).thenReturn(settings);
            HashMap<String, String> hash_map = new HashMap<String, String>();
    
            //Act
            HashMap<String, String> actual = Engine.loadLanguageCodeFile(hash_map);
    
            //Assert
            //perform assertion
        }
    }
    

    Reference Using PowerMock with Mockito: Mocking Static Metho