Search code examples
javaunit-testingjmockit

JMockit - "Missing invocation to mocked type" when mocking System.getProperties()


I am admittedly new to JMockit, but I am for some reason having trouble mocking System.getProperties(). Thanks to the help of following post:

https://stackoverflow.com/questions/25664270/how-can-i-partially-mock-the-system-class-with-jmockit-1-8?lq=1

I can successfully mock System.getProperty() using JMockit 1.12:

@Test
public void testAddSystemProperty_String() {
    final String propertyName = "foo";
    final String propertyValue = "bar";

    new Expectations(System.class) {{
        System.getProperty(propertyName);
        returns(propertyValue);
    }};

    assertEquals(propertyValue, System.getProperty(propertyName));
}

But the eerily similar code for mocking getProperties() barfs:

@Test
public void testAddSystemProperty_String() {
    final String propertyName = "foo";
    final String propertyValue = "bar";

    final Properties properties = new Properties();
    properties.setProperty(propertyName, propertyValue);

    new Expectations(System.class) {{
        System.getProperties();
        returns(properties);
    }};

    assertEquals(1, System.getProperties().size());
}

I get the following exception that points to the "returns" method:

Missing invocation to mocked type at this point; 
please make sure such invocations appear only after 
the declaration of a suitable mock field or parameter

Also, how do I mock both methods at the same time? If I put them in the same Expectations block (with the getProperty() first), then I do not see the exception, but System.getProperties() returns the real system properties, not the mocked ones; though getProperty(propertyName) returns the mocked value. I find that totally wonky behavior.

I see from this post that certain methods cannot be mocked, but System.getProperties() is not on that list:

JMockit NullPointerException on Exceptions block?

I am also finding that a lot of solutions on SO that worked with JMockit 2-3 years ago are totally non-compilable now, so apparently things change a lot.


Solution

  • System.getProperties() is indeed one of the methods excluded from mocking in JMockit 1.12. The exact set of such excluded methods can change in newer versions, as new problematic JRE methods are found.

    There is no need to mock System.getProperty(...) or System.getProperties(), though. The System class provides setProperty and setProperties methods which can be used instead.