Question

I'm building a test, in wich i need to send question, and wait for the answer. Message passing is not the problem. In fact to figure out wich answer correspond to wich question, i use an id. My id is generated using an UUID. an i want to retrieve this id, wich is given as a parameter to a mocked object. It look like this:

  oneOf(message).setJMSCorrelationID(with(correlationId));
           inSequence(sequence);

Where correlationId is the string i'd like to keep for an other expecteation like this one:

   oneOf(session).createBrowser(with(inputChannel), 
           with("JMSType ='pong' AND JMSCorrelationId = '"+correlationId+"'"));

have you got an answer?

Was it helpful?

Solution

One more option to consider, where does the correlation ID come from? Should that activity be injected in so that you can control it and check for it in the test?

OTHER TIPS

You have to create your own actions. Here is mine:

/**
 * puts the parameter array as elements in the list
 * @param parameters A mutable list, will be cleared when the Action is invoked.
 */
public static Action captureParameters(final List<Object> parameters) {
    return new CustomAction("captures parameters") {
        public Object invoke(Invocation invocation) throws Throwable {
            parameters.clear();
            parameters.addAll(Arrays.asList(invocation.getParametersAsArray()));
            return null;
        }
    };
}

You then use it like this (with a static import):

    final List<Object> parameters = new ArrayList<Object>();
    final SomeInterface services = context.mock(SomeInterface.class);
    context.checking(new Expectations() {{
        oneOf(services).createNew(with(6420), with(aNonNull(TransactionAttributes.class)));
            will(doAll(captureParameters(parameters), returnValue(true)));
    }});

To do what you want, you have to implement your own matcher. This is what I hacked up (some null checking left out, and of course I just use well known interfaces for the sample):

 @RunWith(JMock.class)
 public class Scrap {

private Mockery context = new JUnit4Mockery();

@Test
public void testCaptureParameters() throws Exception {
    final CharSequence mock = context.mock(CharSequence.class);
    final ResultSet rs  = context.mock(ResultSet.class);
    final List<Object> parameters = new ArrayList<Object>();
    context.checking(new Expectations(){{
        oneOf(mock).charAt(10);
            will(doAll(JMockActions.captureParameters(parameters), returnValue((char) 0)));
        oneOf(rs).getInt(with(new ParameterMatcher<Integer>(parameters, 0)));
    }});

    mock.charAt(10);
    rs.getInt(10);
}

private static class ParameterMatcher<T> extends BaseMatcher<T> {
    private List<?> parameters;
    private int index;

    private ParameterMatcher(List<?> parameters, int index) {
        this.parameters = parameters;
        this.index = index;
    }

    public boolean matches(Object item) {
        return item.equals(parameters.get(index));
    }

    public void describeTo(Description description) {
        description.appendValue(parameters.get(index));
    }
}
}

i found out an other solution on this site http://www.symphonious.net/2010/03/09/returning-parameters-in-jmock-2/

import org.hamcrest.*;
 import org.jmock.api.*;

 public class CapturingMatcher<T> extends BaseMatcher<T> implements Action {
public T captured;

public boolean matches(Object o) {
    try {
        captured = (T)o;
        return true;
    } catch (ClassCastException e) {
        return false;
    }
}

public void describeTo(Description description) {
    description.appendText("captured value ");
    description.appendValue(captured);
}

public Object invoke(Invocation invocation) throws Throwable {
    return captured;
}
}

It can then be used like:

 context.checking(new Expectations() {{
CapturingMatcher<String> returnCapturedValue = new CapturingMatcher<String>();
allowing(mockObject).getParameter(with(equal("expectedParameterName")), with(returnCapturedValue)); will(returnCapturedValue);
}});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top