Search code examples
javajunitjmockjmockit

How to write custom constraint using Jmock when the method to be mocked is having multiple argument


I am facing difficulty in writing Unit test case for some large code base where I have to mock a lot of classes so that I can proceed with the testing easily. I found in the API documentation of Jmock that the customeconstraint I can use is containing a method

eval(Object argo)

Which will return true if the argument is meeting the expectations.

But my method is invoked with multiple arguments. How can I evaluate the arguments and make sure that the arguments with which the method was invoked is correct. Thanks in advance.


Solution

  • Often it is sufficient to create objects that are equal to the expected parameter values:

    context.checking(new Expectations() {{
      allowing(calculator).add(1, 2);
      will(returnValue(3));
    
      DateTime loadTime = new DateTime(12);
      DateTime fetchTime = new DateTime(14);
      allowing(reloadPolicy).shouldReload(loadTime, fetchTime);
      will(returnValue(false));
    }});
    

    JMock also provides some predefined constraints:

    context.checking(new Expectations() {{
      allowing(calculator).sqrt(with(lessThan(0));
      will(throwException(new IllegalArgumentException());
    }});
    

    You also can use a custom matcher using with:

    context.checking(new Expectations() {{
      DateTime loadTime = new DateTime(12);
      allowing(reloadPolicy).shouldReload(with(equal(loadTime)), with(timeGreaterThan(loadTime));
      will(returnValue(false));
    }});
    

    Here timeGreaterThan could be defined as:

    public class TimeGreaterThanMatcher extends TypeSafeMatcher<DateTime> {
        private DateTime minTime;
    
        public TimeGreaterThanMatcher(DateTime minTime) {
            this.minTime = minTime;
        }
    
        public boolean matchesSafely(DateTime d) {
            return d != null && minTime.isBefore(d);
        }
    
        public StringBuffer describeTo(Description description) {
            return description.appendText("a DateTime greater than ").appendValue(minTime);
        }
    
        public static Matcher<DateTime> timeGreaterThan(DateTime minTime) {
          return new TimeGreaterThanMatcher(minTime);
        }
    }
    

    See the JMock Cookbook for more information