コード例 #1
0
        public void TestMessageListener()
        {
            var mockConnectionFactory = new Mock<ConnectionFactory>();
            var mockConnection = new Mock<IConnection>();
            var onlyChannel = new Mock<IModel>();
            onlyChannel.Setup(m => m.IsOpen).Returns(true);
            onlyChannel.Setup(m => m.CreateBasicProperties()).Returns(() => new BasicProperties());

            var cachingConnectionFactory = new CachingConnectionFactory(mockConnectionFactory.Object);

            mockConnectionFactory.Setup(m => m.CreateConnection()).Returns(mockConnection.Object);
            mockConnection.Setup(m => m.IsOpen).Returns(true);

            var tooManyChannels = new AtomicReference<Exception>();
            var done = false;
            mockConnection.Setup(m => m.CreateModel()).Returns(
                () =>
                {
                    if (!done)
                    {
                        done = true;
                        return onlyChannel.Object;
                    }

                    tooManyChannels.LazySet(new Exception("More than one channel requested"));
                    var channel = new Mock<IModel>();
                    channel.Setup(m => m.IsOpen).Returns(true);
                    return channel.Object;
                });

            var consumer = new BlockingCollection<IBasicConsumer>(1);

            onlyChannel.Setup(m => m.BasicConsume(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<IBasicConsumer>())).Callback<string, bool, IBasicConsumer>(
                (a1, a2, a3) => consumer.Add(a3));

            var commitLatch = new CountdownEvent(1);
            onlyChannel.Setup(m => m.TxCommit()).Callback(
                () =>
                {
                    if (commitLatch.CurrentCount > 0)
                    {
                        commitLatch.Signal();
                    }
                });

            var latch = new CountdownEvent(1);
            var container = new SimpleMessageListenerContainer(cachingConnectionFactory);
            container.MessageListener = new Action<Message>(
                message =>
                {
                    var rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
                    rabbitTemplate.ChannelTransacted = true;

                    // should use same channel as container
                    rabbitTemplate.ConvertAndSend("foo", "bar", "baz");
                    if (latch.CurrentCount > 0)
                    {
                        latch.Signal();
                    }
                });

            container.QueueNames = new[] { "queue" };
            container.ChannelTransacted = true;
            container.ShutdownTimeout = 100;
            container.TransactionManager = DummyTxManager.Instance();
            container.AfterPropertiesSet();
            container.Start();

            IBasicConsumer currentConsumer;
            consumer.TryTake(out currentConsumer, this.timeout);
            Assert.IsNotNull(currentConsumer, "Timed out getting consumer.");
            currentConsumer.HandleBasicDeliver("qux", 1, false, "foo", "bar", new BasicProperties(), new byte[] { 0 });

            Assert.IsTrue(latch.Wait(new TimeSpan(0, 0, 10)));

            var e = tooManyChannels.Value;
            if (e != null)
            {
                throw e;
            }

            mockConnection.Verify(m => m.CreateModel(), Times.Once());
            Assert.True(commitLatch.Wait(new TimeSpan(0, 0, 10)));
            onlyChannel.Verify(m => m.TxCommit(), Times.Once());
            onlyChannel.Verify(m => m.BasicPublish(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<IBasicProperties>(), It.IsAny<byte[]>()), Times.Once());

            // verify close() was never called on the channel
            var cachedChannelsTransactionalField = typeof(CachingConnectionFactory).GetField("cachedChannelsTransactional", BindingFlags.NonPublic | BindingFlags.Instance);
            var channels = (LinkedList<IChannelProxy>)cachedChannelsTransactionalField.GetValue(cachingConnectionFactory);
            Assert.AreEqual(0, channels.Count);

            container.Stop();
            container.Dispose();
            container = null;
        }