2

I'm trying to write a unit test that involves using legacy code. Problem is, from what I can tell, the legacy code uses a key/value pair from a property file to initialize one of its final static private members, and I haven't the slightest as to where that property file might be (the entire application is quite huge).

So, in my test, I want to do something like this (using Mockito):

LegacyClass legacyClass = mock(LegacyClass.class);

I end up getting a ExceptionInInitializationError which indicates it can't find a certain property key.

In LegacyClass.java, there's:

private static final int LEGACY_PROPERTY = 
    Integer.parseInt(LegacyPropertyManager.getProp("legacy.property.key"));

Is there a way to write a test that uses this legacy class, even if the property key it's looking for doesn't exist? Can it be mocked somehow?

dashik
  • 67
  • 1
  • 1
  • 6
  • Add your own properties file for teh unit test like [here](http://stackoverflow.com/questions/1557562/does-junit-support-properties-files-for-tests) – Rob Garwood Aug 01 '13 at 15:48
  • @RobGarwood But the problem is that it's the legacy class that uses the property - how would make LegacyClass use my own properties file upon instantiation instead of the one looked up by LegacyPropertyManager? – dashik Aug 01 '13 at 16:30
  • @JeffBowman Clever indeed; though I'm not too sure how to use `mockStatic` to mock `getProp` so that it uses my property file. In my unit test I tried mocking `LegacyPropertyManager` and then setting up a `when(...).thenReturn(...)` like in the example you linked to, but it looks like LegacyClass still uses the original. Was there an extra step I need to do? – dashik Aug 01 '13 at 18:39
  • @dashik Promoting to an answer to give it its own thread. – Jeff Bowman Aug 01 '13 at 18:56

2 Answers2

2

You might not get very far without a clever library like PowerMock. Note that your LegacyClass.java initializes this property in a static final field, which means that the initializer will run as soon as it's loaded. PowerMock uses deeper magic (read: bytecode manipulation) to allow you to mock the static getProp method you cited above.

You'll need to do the following to get started with PowerMockito:

@RunWith(PowerMockRunner.class)
@PrepareForTest(LegacyPropertyManager.class)
public class YourClass {

  @Before public void stubLegacyPropertyManager() {
    Mockito.when(LegacyPropertyManager.getProp("legacy.property.key"))
        .thenReturn("42");
  }

  @Test public void yourTest() {
    // ...
  }
}

Note the class-level annotations, which respectively allow for PowerMock initialization and register the correct class for static-level mocking.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • Here in this case I am not getting the `getProp`. Getting error. In eclipse recomndation it is asking to do `getProperties.` But test cases are failing. – David Jul 12 '18 at 04:23
  • @David It sounds like you might have a slightly different problem. The comments aren't a good place to solve it, as the comment box is small and formatting-restricted; please consider asking a new top-level question. To show the research/attempts, you can link to this answer and describe what parts about it are inapplicable for you. – Jeff Bowman Jul 12 '18 at 04:42
  • i add a question here. Please have a look. https://stackoverflow.com/questions/51297854/mock-test-is-getting-failed-because-of-properties-file – David Jul 12 '18 at 05:23
1

An example of mocking a properties file, completely ignoring where it is would be the following. You can create your own set of key/value pairs right in the mocked properties object.

Properties mockProperties = mock(Properties.class);
when((mockProperties.getProperty("keyName"))).thenReturn("value");

Getting this object to be used by your legacy class may involve code changes to the legacy class such as changing the private properties object to protected or creating a set method.

When unable to enhance the legacy code, I know you can venture into the area of partial mocks/spies (Mockito 1.8) such as described in the following post .. Mockito bypass static method for testing and its link to Effective Mockito. I haven't used them so I cannot offer more help. Good luck.

Community
  • 1
  • 1
Steven Mai
  • 63
  • 7
  • Useful to know, but unfortunately I'm not allowed to touch the legacy class code. – dashik Aug 01 '13 at 16:50
  • If you're not allowed to touch the class code, then what will you do if your testing uncovers a bug in that code? – Dawood ibn Kareem Aug 01 '13 at 20:02
  • Ah, just to clear things up, I'm not testing the legacy code. It's been in use since the late 90's (albeit, poorly written by today's standards), so we know it's functional. I just needed to write a class (and unit test) which uses that legacy code, but its bad design gave me a hard time mocking it. I put in a request with my boss about gaining permission for refactoring, and he said he would try to do something about it. – dashik Aug 02 '13 at 01:18