27

There is a message(text), which format and content i definitely know.
For now,class in Java,that parses and reads this message from file,is implemented.

In real world, this message will come from Message Queue.

For now I should simulate, mock or generate Message Queue on my local PC for testing purposes.

Java spec(java jms):

JMS provider: A messaging system that implements the JMS specification.
JMS clients: Java applications that send and receive messages.
Messages: Objects that are used to communicate information between JMS clients.

Concerning this specification, i need JMS provider.

JMS client-it's my class that reads message.
Message itself i know.

So the question is how to start message queue?
How can i simulate it programmaticaly from Java code? Can i mock it somehow?

Thanks.

sergionni
  • 13,290
  • 42
  • 132
  • 189
  • 1
    Why go to all that trouble? Why not just install a local JMS provider on your workstation and use it? You can download open source ones and trial versions of vendor JMS providers. Since it's JMS, any compliant implementation will work for unit testing. – T.Rob Oct 19 '10 at 16:53
  • That is i ask, so i need install JMS provider. What could you advise me? thank you – sergionni Oct 19 '10 at 16:57
  • Well, I'm an IBMer so I have to suggest the trial of WMQ. :-) But I see you've already found ActiveMQ which you can use for development without it expiring. On the other hand, whatever you use in production would be best to develop on so move to that once you know what it will be. – T.Rob Oct 19 '10 at 23:45
  • 2
    Easy way to mock a JMS Queue. Refer below website https://dzone.com/articles/mockrunner-jms-spring-unit – Yallaling Goudar Dec 01 '16 at 10:49

5 Answers5

11

To test an application in isolation when the real production JMS provider is not available you can use one of:

  1. JMS mock:
    When testing your applications you can simulate the non-existing dependencies using test doubles. You can use a JMS mock which will simulate the behaviour of a real JMS provider. API simulation tools will allow you to create JMS mocks (just choose a tool that supports JMS, for example Traffic Parrot). Using a JMS mock will allow you for a high level of flexibility during testing. You will be able to test typical production-like test scenarios but also hypothetical situations by setting up your mock to return almost any type of message. You will also be able to simulate different types of errors, which is often hard to do with real JMS providers. Have a look at this introduction video to JMS service virtualization for ActiveMq (service virtualization is a different name for a mock) or this one for IBM MQ. Note, these videos are from Traffic Parrot, but the principle described there will apply to any tool you choose.

  2. JMS provider test instance:
    You can run a JMS provider on your laptop or in one of your test environments and connect your application to it instead of the production provider. When you use open source providers in production like ActiveMQ or RabbitMQ, it should be easy to run one of them on your laptop as well because they are lightweight and free. For IBM Websphere MQ, you can use the free IBM MQ for Developers.

  3. JMS class mock:
    You can use Mockito in unit tests to mock interactions with JMS classes. This solution comes with all the trade-offs of unit testing. For more information on those see testing pyramid.

If you would like to black box test your application, use one of the solutions I have described above.

JoshMc
  • 10,239
  • 2
  • 19
  • 38
Wojtek
  • 1,410
  • 2
  • 16
  • 31
6

If you use Spring Integration, you can do this pretty easily. It has a very basic, abstract "Channel" implementation. You can create and test your producers and consumers, and when you're ready to move a step further, you just specify a JMS adapter on top of your Channel.

jcalvert
  • 3,628
  • 2
  • 19
  • 13
0

Generally it is a bad practice to mock or simulate an external system, such as JMS. A better idea would be to abstract your logic into a standalone bean, implement a delegation layer that would bridge JMS with your bean. With such design you can test your bean in isolation from JMS and then have system test that would test the whole integration with real JMS system.

As for in-process JMS you can look at SomnifugiJMS.

Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
  • 45
    I completely disagree. Mocking an external system is critical for unit tests, especially if you rely on an external interface and don't want to turn your unit tests into integration tests. – Andres Kievsky Sep 27 '12 at 02:09
  • 1
    @ank - It *is* a bad practice to mock an external system. The solution is to create an interface to that system within your own application (the bean that Eugene Kuleshov is referring to) which handles communication to the outside system, and then in test, you mock *that*. Trying to mock the whole external system is expensive and messy. – Ickster May 22 '15 at 17:18
  • 2
    @Ickster that's the definition of a mock… (I know this is rather old, but) can you provide an example to the distinction you believe you're making? – davemyron Mar 11 '16 at 20:55
  • @davemyron -- Good question. I know I was working on something at the time that I wrote that that's a perfect example of what I was trying to get at, but darned if I can remember exactly what it was. If I think of it, I'll let you know. – Ickster Mar 11 '16 at 21:04
  • JMS is, almost in it's entirely, an interface. So mocking it, while non-trivial, is certainly within the realm of acceptable-but-painful practices. If you're using something specific from an implementation, which it seems many people do, then better advice might be "stop doing that". – Mykel Alvis May 27 '16 at 21:50
  • 3
    Recently tools like http://wiremock.org, https://hoverfly.io/ and http://www.mbtest.org/ are becoming increasingly popular for creating out-of-process (over-the-wire) mocks for HTTP APIs. The same principle of out-of-process mocking can be applied to JMS APIs as well with API simulation tools that support JMS https://en.wikipedia.org/wiki/Comparison_of_API_simulation_tools I have mentioned HTTP here because it is more popular than JMS and its easier to see the market trends there. – Wojtek Dec 08 '17 at 13:40
0

In the meantime almost every Message Broker has an embedded version which runs within the JVM only. Thus you can use this for tests instead of a dependent external JMS Broker.

kladderradatsch
  • 596
  • 5
  • 18
-1

Generally I agree with Eugene Kuleshov. But if you still need such mocking I'd suggest you to use BlckingQueue from java.util.concurent package. I think it is not a big problem to wrap it with javax.jms.Queue interface. BTW it is a good idea for some kind of open-source project.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • I've just found Apache ActiveMQ. Trying this for first. – sergionni Oct 19 '10 at 20:03
  • I agree with Eugene Kuleshov also. I think Dan North (founder of BDD probably agrees with him too) and probably anyone else with any design nous also agrees I imagine. If you've tangled up your business logic in your application up with the entry point for a JMS queue, then you've made a design mistake in your application. The better option is to fix the design mistake (if you can). However, sometimes that is not possible. You may be working with a large legacy code base responsible for a mission critical system that can't easily be fixed without change risk. Eugene Kuleshov is still right. – John Deverall May 24 '22 at 04:59