Microsoft Message Queue (MSMQ) in Ruby

gem 'test-unit'
gem 'minitest'

require 'test/unit'
require 'win32ole'
require 'json'

class MsmqTest < Test::Unit::TestCase

  MQ_DENY_NONE      = 0
  MQ_RECEIVE_ACCESS = 1
  MQ_SEND_ACCESS    = 2
  MQ_NO_TRANSACTION = 0
  MQ_SINGLE_MESSAGE = 3
  MQ_PEEK_ACCESS    = 32

  def setup
    # Could use Win32API to call MQPurgeQueue in mqrt.dll.
    # Otherwise, purge the queue manually via Computer Management tool before running tests.
  end

  def test_send_receive_plaintext
    message       = WIN32OLE.new('MSMQ.MSMQMessage')
    message.Label = 'PlainText Message'
    message.Body  = 'This is a test message'

    assert_message_equal message
  end

  def test_send_receive_json
    message       = WIN32OLE.new('MSMQ.MSMQMessage')
    message.Label = 'JSON Message'
    message.Body  = {
        id:   123,
        name: 'Test'
    }.to_json

    assert_message_equal message
  end

  private

  def assert_message_equal(message)
    queue_info  = get_queue_info
    transaction = queue_info.IsTransactional2 ? MQ_SINGLE_MESSAGE : MQ_NO_TRANSACTION

    # Write a message to the queue
    queue_write = queue_info.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    if queue_write.IsOpen2
      message.Send(queue_write, transaction)
      queue_write.Close
    else
      assert_fail_assertion 'queue is not open for sending'
    end

    # Read the message back
    queue_read = queue_info.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    if queue_read.IsOpen2
      message_received = queue_read.Receive(transaction, false, true, 3000) # Timeout in 3 seconds
      assert_not_nil message_received, 'message_received is nil'
      assert_equal message.Label, message_received.Label
      assert_equal message.Body, message_received.Body
      queue_read.Close
    else
      assert_fail_assertion 'queue is not open for receiving'
    end

  end

  def get_queue_info
    queue_info          = WIN32OLE.new('MSMQ.MSMQQueueInfo')
    queue_info.PathName = '.\private$\MyQueue'
    queue_info
  end

end

Sliding Sidebar