简体   繁体   中英

Unit Test IBM MQ

I'm new at the MQ topic.

How do I Test/Unit-Test my Java Services, which do actions against a real Queue. My classes do connections, deletes etc.

Is there any way to test these services without performing actions against the productive Queues?

@Service
public class QueueConnectionService {

    private final MQConfigMapping configMapping;

    private MQQueueManager queueManager;

    @Autowired
    public QueueConnectionService(MQConfigMapping configMapping) {
        this.configMapping = configMapping;
    }


    MQQueue connect(String queuePropertyTitle, int openOptions, String queueName) throws MQException {
        MQEnvironment.hostname = configMapping.getNamed().get(queuePropertyTitle).getHostname();
        MQEnvironment.channel = configMapping.getNamed().get(queuePropertyTitle).getChannel();
        MQEnvironment.port = configMapping.getNamed().get(queuePropertyTitle).getPort();
        MQEnvironment.userID = configMapping.getNamed().get(queuePropertyTitle).getUser();
        MQEnvironment.password = configMapping.getNamed().get(queuePropertyTitle).getPassword();
        queueManager = new MQQueueManager(configMapping.getNamed().get(queuePropertyTitle).getQueueManager());
        return queueManager.accessQueue(queueName, openOptions);
    }
}

This is my QueueConnectionService, but I have no clue how to use this one at local tests.

In order to do unit tests , you will need to mock the IBM MQ classes, using a framework like Mockito .

One issue you'll encounter is that you cannot mock the call to the MQQueueManager constructor, as the new operator cannot be mocked. I would recommend creating a MqQueueManagerFactory service, autowire this service into your QueueConnectionService and mock it in the test.

Your unit test will end up looking like this:

@ExtendWith(MockitoExtension.class)
class QueueConnectionServiceTest {

  private static final String TITLE = "Some random string";
  private static final String QUEUE_MANAGER = "Actual value does not matter";
  private static final String NAME = "Really. Those constants are magic strings.";
  private static final int OPTIONS = 42;

  @InjectMock
  private QueueConnectionService service;

  @Mock(answer = RETURNS_DEEP_STUBS)
  private MQConfigMapping configMapping;

  @Mock
  private MqConnectionManagerFactory connectionManagerFactory;

  @Mock
  private MQConnectionManager connectionManager;

  @Mock
  private MQQueue queue;

  @Test
  void should_provide_queue() {
    when(configMapping.getNamed().get(TITLE).getQueueManager()).thenReturn(QUEUE_MANAGER);
    // repeat above line for each configuration parameter.
    // Alternatively, create a config object and:
    when(configMapping.getNamed().get(TITLE)).thenReturn(config);

    when(connectionManagerFactory.create(QUEUE_MANAGER)).thenReturn(connectionManager);
    when(connectionManager.accessQueue(NAME, OPTIONS)).thenReturn(queue);

    var actual = service.connect(TITLE, OPTIONS, NAME);

    assertSame(actual, queue);
  }

}

(This is with JUnit 5 and Mockito . You would have something slightly different with another testing framework or another mocking framework.)

As a side note, creating a queue manager at each connection smells bad. You probably want to create it once in an @PostConstruct method.

You could set up a development queue manager to run unit tests against. See https://developer.ibm.com/learningpaths/ibm-mq-badge/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM