1

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

Laxmi Kadariya
  • 1,103
  • 1
  • 14
  • 34
  • 3
    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 – Nkosi Dec 03 '18 at 18:28
  • The code is also tightly coupled to implementation concerns like the file reader and buffer reader. Are you planning to read actual file when testing? – Nkosi Dec 03 '18 at 18:30
  • 1
    I agree with @Nkosi; I'm not seeing anything here for you *to* mock except maybe the IO pieces. It does raise the strong question of where `FILENAME` even comes from, though. – Makoto Dec 03 '18 at 18:30
  • What are you actually trying to test with that method? – Nkosi Dec 03 '18 at 18:32
  • @Nkosi I am trying to test the file path is correct or not. and also test some part of the real file as well – Laxmi Kadariya Dec 03 '18 at 18:37
  • @LaxmiKadariya Correct in what way. That is does not throw an exception when it tries to read the actual file? – Nkosi Dec 03 '18 at 18:44
  • @Nkosi yes I should not get exception and want to have returned hash map so that I can verify my data in it. – Laxmi Kadariya Dec 03 '18 at 18:46
  • @Nkosi How can I get my control in my loadLanguageCodeFile method after I run my test case? I tried to call MSmock.loadLanguageCodeFile(hash_map); – Laxmi Kadariya Dec 03 '18 at 18:47
  • 1
    @LaxmiKadariya Call the actual static member under test. *ie* `HashMap result = Engine.loadLanguageCodeFile(hash_map);` – Nkosi Dec 03 '18 at 18:49

1 Answers1

3

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

Nkosi
  • 235,767
  • 35
  • 427
  • 472