Search code examples
javaunit-testingmockingjmock

Migrating from jMock1 custom invocation matchers to jMock2


I am using JMock-2.6.0. I have a map containing the names of methods and their expected return values. I want to invoke a method on a mock object created using JMock.

Earlier I was able to this using JMock 1 as it follows following syntax:

mockObj.stubs().method(mymap.getKey()).will(new ReturnStub(mymap.getValue()));

But I am not sure, if there is a way to achieve this using JMock-2.

JMock-2's documentation is insufficient.


Solution

  • I believe this is the documentation you've been looking for:

    Match Objects or Methods

    Although matchers are normally used to specify acceptable parameter values, they can also be used to specify acceptable objects or methods in an expectation, using an API syntax similar to that of jMock 1. To do so, use a matcher where you would normally refer to a mock object directly in the invocation count clause. Then chain clauses together to define the expected invocation.

    Their example includes:

    To allow invocations of any bean property getter on any mock object:

    allowing (any(Object.class)).method("get.*").withNoArguments();
    

    For example you can use the following allowing... portion in a loop to achieve a similar result.

    An sample test:

    Interface:

    public interface ThingOneI {
    
        public abstract String getData();
    
        public abstract void setData(String data);
    
        public abstract String getRequest();
    
        public abstract void setRequest(String request);
    
    }
    

    Impl:

    public class ThingOne implements ThingOneI {
    
        private String data;
        private String request;
    
        public ThingOne() {
    
        }
    
     @Override
        public String getData() {
            return data;
        }
    
    
     @Override
        public void setData(String data) {
            this.data = data;
        }
    
     @Override
        public String getRequest() {
            return request;
        }
    
     @Override
        public void setRequest(String request) {
            this.request = request;
        }
    
    
    
    }
    

    Junit test:

    import org.jmock.Expectations;
    import org.jmock.Mockery;
    import org.junit.Before;
    import org.junit.Test;
    
    public class ThingOneTest {
    
        Mockery context = new Mockery();
    
        @Before
        public void setUp() throws Exception {
        }
    
        @Test
        public void test() {
            ThingOneI thingOne = context.mock(ThingOneI.class);
            Map<String, String> methMap = new HashMap<String, String>();
            methMap.put("getData", "5");
    
            context.checking(new Expectations() {{
    
                for (Map.Entry<String, String> entry : methMap.entrySet())
                    allowing(any(ThingOneI.class))
                        .method(entry.getKey())
                        .with(any(String.class));
                        will(returnValue(entry.getValue()));
                }
    
             }});
    
             System.out.println(thingOne.getData());
    
        }
    }