@Before
  public void init() {
    PullContext pullContext = createMock(PullContext.class);

    expect(pullContext.pull("pull1")).andReturn(111).anyTimes();
    expect(pullContext.pull("pull2")).andReturn(222).anyTimes();

    Set<String> names = createHashSet(Arrays.asList("pull1", "pull2"));
    expect(pullContext.getToolNames()).andReturn(names).anyTimes();

    expect(pullContext.pull(org.easymock.EasyMock.<String>anyObject())).andReturn(null).anyTimes();

    replay(pullContext);

    parent = new PullableMappedContext(pullContext);
    parent.put("parent", 333);

    context = new MappedContext(parent);
    context.put("child", 444);
  }
/** @author Christoph Deppisch */
public class JmsMessageReceiverTest {

  private ConnectionFactory connectionFactory =
      org.easymock.EasyMock.createMock(ConnectionFactory.class);
  private Connection connection = EasyMock.createMock(Connection.class);
  private Session session = EasyMock.createMock(Session.class);
  private Destination destination = EasyMock.createMock(Destination.class);
  private Queue destinationQueue = EasyMock.createMock(Queue.class);
  private MessageConsumer messageConsumer = EasyMock.createMock(MessageConsumer.class);

  private JmsTemplate jmsTemplate = EasyMock.createMock(JmsTemplate.class);

  @Test
  public void testReceiveMessageWithJmsTemplate() {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setJmsTemplate(jmsTemplate);

    Map<String, Object> controlHeaders = new HashMap<String, Object>();
    final Message<String> controlMessage =
        MessageBuilder.withPayload("<TestRequest><Message>Hello World!</Message></TestRequest>")
            .copyHeaders(controlHeaders)
            .build();

    reset(jmsTemplate, connectionFactory, destination);

    jmsTemplate.setReceiveTimeout(5000L);
    expectLastCall().once();

    expect(jmsTemplate.getDefaultDestination()).andReturn(destination).atLeastOnce();

    expect(jmsTemplate.receiveAndConvert()).andReturn(controlMessage);

    replay(jmsTemplate, connectionFactory, destination);

    Message<?> receivedMessage = receiver.receive();
    Assert.assertTrue(receivedMessage.equals(controlMessage));

    verify(jmsTemplate, connectionFactory, destination);
  }

  @Test
  public void testWithDestination() throws JMSException {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setConnectionFactory(connectionFactory);

    receiver.setDestination(destination);

    Map<String, Object> controlHeaders = new HashMap<String, Object>();
    final Message<String> controlMessage =
        MessageBuilder.withPayload("<TestRequest><Message>Hello World!</Message></TestRequest>")
            .copyHeaders(controlHeaders)
            .build();

    Map<String, String> headers = new HashMap<String, String>();

    reset(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    expect(connectionFactory.createConnection()).andReturn(connection).once();
    expect(connection.createSession(anyBoolean(), anyInt())).andReturn(session).once();
    expect(session.getTransacted()).andReturn(false).once();
    expect(session.getAcknowledgeMode()).andReturn(Session.AUTO_ACKNOWLEDGE).once();

    expect(session.createConsumer(destination, null)).andReturn(messageConsumer).once();

    connection.start();
    expectLastCall().once();

    expect(messageConsumer.receive(5000L))
        .andReturn(
            new TextMessageImpl(
                "<TestRequest><Message>Hello World!</Message></TestRequest>", headers))
        .once();

    replay(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    Message<?> receivedMessage = receiver.receive();
    Assert.assertEquals(receivedMessage.getPayload(), controlMessage.getPayload());

    verify(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);
  }

  @Test
  public void testReceiveMessageWithDestinationName() throws JMSException {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setConnectionFactory(connectionFactory);

    receiver.setDestinationName("myDestination");

    Map<String, Object> controlHeaders = new HashMap<String, Object>();
    final Message<String> controlMessage =
        MessageBuilder.withPayload("<TestRequest><Message>Hello World!</Message></TestRequest>")
            .copyHeaders(controlHeaders)
            .build();

    Map<String, String> headers = new HashMap<String, String>();

    reset(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    expect(connectionFactory.createConnection()).andReturn(connection).once();
    expect(connection.createSession(anyBoolean(), anyInt())).andReturn(session).once();
    expect(session.getTransacted()).andReturn(false).once();
    expect(session.getAcknowledgeMode()).andReturn(Session.AUTO_ACKNOWLEDGE).once();

    expect(session.createQueue("myDestination")).andReturn(destinationQueue).once();

    expect(session.createConsumer(destinationQueue, null)).andReturn(messageConsumer).once();

    expect(messageConsumer.receive(5000L))
        .andReturn(
            new TextMessageImpl(
                "<TestRequest><Message>Hello World!</Message></TestRequest>", headers))
        .once();

    connection.start();
    expectLastCall().once();

    replay(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    Message<?> receivedMessage = receiver.receive();
    Assert.assertEquals(receivedMessage.getPayload(), controlMessage.getPayload());

    verify(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);
  }

  @Test
  public void testReceiveMessageTimeout() throws JMSException {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setConnectionFactory(connectionFactory);

    receiver.setDestination(destination);

    reset(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    expect(connectionFactory.createConnection()).andReturn(connection).once();
    expect(connection.createSession(anyBoolean(), anyInt())).andReturn(session).once();
    expect(session.getTransacted()).andReturn(false).once();
    expect(session.getAcknowledgeMode()).andReturn(Session.AUTO_ACKNOWLEDGE).once();

    expect(session.createConsumer(destination, null)).andReturn(messageConsumer).once();

    expect(messageConsumer.receive(5000L)).andReturn(null).once();

    connection.start();
    expectLastCall().once();

    replay(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    try {
      receiver.receive();
    } catch (ActionTimeoutException e) {
      Assert.assertTrue(
          e.getMessage().startsWith("Action timed out while receiving JMS message on"));
      return;
    }

    Assert.fail(
        "Missing " + CitrusRuntimeException.class + " because of receiveing message timeout");
  }

  @Test
  public void testWithCustomTimeout() throws JMSException {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setConnectionFactory(connectionFactory);

    receiver.setDestination(destination);

    receiver.setReceiveTimeout(10000L);

    Map<String, Object> controlHeaders = new HashMap<String, Object>();
    final Message<String> controlMessage =
        MessageBuilder.withPayload("<TestRequest><Message>Hello World!</Message></TestRequest>")
            .copyHeaders(controlHeaders)
            .build();

    Map<String, String> headers = new HashMap<String, String>();

    reset(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    expect(connectionFactory.createConnection()).andReturn(connection).once();
    expect(connection.createSession(anyBoolean(), anyInt())).andReturn(session).once();
    expect(session.getTransacted()).andReturn(false).once();
    expect(session.getAcknowledgeMode()).andReturn(Session.AUTO_ACKNOWLEDGE).once();

    expect(session.createConsumer(destination, null)).andReturn(messageConsumer).once();

    connection.start();
    expectLastCall().once();

    expect(messageConsumer.receive(10000L))
        .andReturn(
            new TextMessageImpl(
                "<TestRequest><Message>Hello World!</Message></TestRequest>", headers))
        .once();

    replay(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    Message<?> receivedMessage = receiver.receive();
    Assert.assertEquals(receivedMessage.getPayload(), controlMessage.getPayload());

    verify(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);
  }

  public void testWithMessageHeaders() throws JMSException {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setConnectionFactory(connectionFactory);

    receiver.setDestination(destination);

    Map<String, Object> controlHeaders = new HashMap<String, Object>();
    controlHeaders.put("Operation", "sayHello");
    final Message<String> controlMessage =
        MessageBuilder.withPayload("<TestRequest><Message>Hello World!</Message></TestRequest>")
            .copyHeaders(controlHeaders)
            .build();

    Map<String, String> headers = new HashMap<String, String>();
    headers.put("Operation", "sayHello");

    reset(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    expect(connectionFactory.createConnection()).andReturn(connection).once();
    expect(connection.createSession(anyBoolean(), anyInt())).andReturn(session).once();
    expect(session.getTransacted()).andReturn(false).once();
    expect(session.getAcknowledgeMode()).andReturn(Session.AUTO_ACKNOWLEDGE).once();

    expect(session.createConsumer(destination, null)).andReturn(messageConsumer).once();

    connection.start();
    expectLastCall().once();

    expect(messageConsumer.receive(5000L))
        .andReturn(
            new TextMessageImpl(
                "<TestRequest><Message>Hello World!</Message></TestRequest>", headers))
        .once();

    replay(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    Message<?> receivedMessage = receiver.receive();
    Assert.assertEquals(receivedMessage.getPayload(), controlMessage.getPayload());
    Assert.assertTrue(receivedMessage.getHeaders().containsKey("Operation"));
    Assert.assertTrue(receivedMessage.getHeaders().get("Operation").equals("sayHello"));

    verify(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);
  }

  @Test
  public void testWithMessageSelector() throws JMSException {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setConnectionFactory(connectionFactory);

    receiver.setDestination(destination);

    Map<String, Object> controlHeaders = new HashMap<String, Object>();
    final Message<String> controlMessage =
        MessageBuilder.withPayload("<TestRequest><Message>Hello World!</Message></TestRequest>")
            .copyHeaders(controlHeaders)
            .build();

    Map<String, String> headers = new HashMap<String, String>();

    reset(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    expect(connectionFactory.createConnection()).andReturn(connection).once();
    expect(connection.createSession(anyBoolean(), anyInt())).andReturn(session).once();
    expect(session.getTransacted()).andReturn(false).once();
    expect(session.getAcknowledgeMode()).andReturn(Session.AUTO_ACKNOWLEDGE).once();

    expect(session.createConsumer(destination, "Operation = 'sayHello'"))
        .andReturn(messageConsumer)
        .once();

    connection.start();
    expectLastCall().once();

    expect(messageConsumer.receive(5000L))
        .andReturn(
            new TextMessageImpl(
                "<TestRequest><Message>Hello World!</Message></TestRequest>", headers))
        .once();

    replay(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    Message<?> receivedMessage = receiver.receiveSelected("Operation = 'sayHello'");
    Assert.assertEquals(receivedMessage.getPayload(), controlMessage.getPayload());

    verify(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);
  }

  @Test
  public void testWithMessageSelectorAndCustomTimeout() throws JMSException {
    JmsMessageReceiver receiver = new JmsMessageReceiver();
    receiver.setConnectionFactory(connectionFactory);

    receiver.setDestination(destination);
    receiver.setReceiveTimeout(10000L);

    Map<String, Object> controlHeaders = new HashMap<String, Object>();
    final Message<String> controlMessage =
        MessageBuilder.withPayload("<TestRequest><Message>Hello World!</Message></TestRequest>")
            .copyHeaders(controlHeaders)
            .build();

    Map<String, String> headers = new HashMap<String, String>();

    reset(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    expect(connectionFactory.createConnection()).andReturn(connection).once();
    expect(connection.createSession(anyBoolean(), anyInt())).andReturn(session).once();
    expect(session.getTransacted()).andReturn(false).once();
    expect(session.getAcknowledgeMode()).andReturn(Session.AUTO_ACKNOWLEDGE).once();

    expect(session.createConsumer(destination, "Operation = 'sayHello'"))
        .andReturn(messageConsumer)
        .once();

    connection.start();
    expectLastCall().once();

    expect(messageConsumer.receive(10000L))
        .andReturn(
            new TextMessageImpl(
                "<TestRequest><Message>Hello World!</Message></TestRequest>", headers))
        .once();

    replay(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);

    Message<?> receivedMessage = receiver.receiveSelected("Operation = 'sayHello'");
    Assert.assertEquals(receivedMessage.getPayload(), controlMessage.getPayload());

    verify(jmsTemplate, connectionFactory, destination, connection, session, messageConsumer);
  }
}