开发者

Using jmock how to reuse parameter

开发者 https://www.devze.com 2023-01-01 05:19 出处:网络
I\'m building a test, in which I need to send question, and wait for the answer. Message passing is not the problem. In fact to figure out which answer corresponds to which question, I use an id. My i

I'm building a test, in which I need to send question, and wait for the answer. Message passing is not the problem. In fact to figure out which answer corresponds to which question, I use an id. My id is generated using an UUID. I want to retrieve this id, which is given as a parameter to a mocked ob开发者_Python百科ject. It look like this:

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

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

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

have you got an answer?


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));
    }
}
}


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?


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);
}});
0

精彩评论

暂无评论...
验证码 换一张
取 消