如何让CreateUsingInMemory()与MassTransit一起使用?

时间:2015-10-18 18:06:40

标签: c# masstransit

这是我的整个代码。我认为测试应该通过,但它失败了。我(尝试失败)试图将一些重载用于Consumer

using MassTransit;
using NUnit.Framework;
using System.Threading.Tasks;

namespace MassTransitTests
{
    public class Message
    {
    }

    public class MessageConsumer : IConsumer<Message>
    {
        public static int ConsumedCount
        {
            get;
            private set;
        }

        public Task Consume(ConsumeContext<Message> context)
        {
            ConsumedCount++;
            return Task.FromResult(0);
        }
    }

    [TestFixture]
    public class MassTransitTest
    {
        [Test]
        public async Task BasicTestAsync()
        {
            // Arrange
            var control = Bus.Factory.CreateUsingInMemory(configure =>
            {
                configure.ReceiveEndpoint("myQueue", endpoint =>
                {
                    endpoint.Consumer<MessageConsumer>();
                });
            });

            // Act
            using (var handle = control.Start())
            {
                await control.Publish(new Message());
                await control.Publish(new Message());
            }

            // Assert
            Assert.That(MessageConsumer.ConsumedCount, Is.EqualTo(2));
        }
    }
}

他们的documentation显示了这一点,这就是我正在做的事情:

var busControl = Bus.Factory.CreateUsingInMemory(cfg =>
{
    cfg.ReceiveEndpoint("queue_name", ep =>
    {
       //configure the endpoint
    })
});

我做错了什么/我需要在我的安排/法案中做些什么才能让我的Assert工作?

1 个答案:

答案 0 :(得分:3)

在完成测试后,我发现了我所缺少的内容:

[1]你需要*到await BusHandle.Ready,我没有这样做。 *(测试没有这个 - 至少我第一次运行它,但这可能只是一种对我有利的竞争条件......)

[2]当公交车收到我猜的消息时,Publish的呼叫显然已经完成 - 而不是当消息的处理者/消费者完成了他们的工作时。因此,如果您正在测试,则需要通知调用代码处理程序已完成。这是一种方法 - 使用TaskCompletionSource<T>(类似于我在其代码库中找到的)。显然,我的线程安全性可能并不完美,我的lock用法有点像雪橇式,但这说明了这一点:

using MassTransit;
using NUnit.Framework;
using System.Threading.Tasks;

namespace MassTransitTests
{
    public class Message
    {
    }

    public class MessageConsumer : IConsumer<Message>
    {        
        public static int TargetConsumedCount
        {
            get { return _targetConsumedCount; }
            set
            {
                lock (_lock)
                {
                    _targetConsumedCount = value;
                    CheckTargetReached();
                }
            }
        }

        private static void CheckTargetReached()
        {
            if (_consumedCount >= TargetConsumedCount)
            {
                _targetReached.SetResult(true);
            }
        }

        public static Task<bool> TargetReached { get; private set; }

        private static int _consumedCount;
        private static int _targetConsumedCount;
        private static TaskCompletionSource<bool> _targetReached;
        private static object _lock;

        static MessageConsumer()
        {
            _lock = new object();
            _targetReached = new TaskCompletionSource<bool>();
            TargetReached = _targetReached.Task;
        }

        public Task Consume(ConsumeContext<Message> context)
        {
            lock (_lock)
            {
                _consumedCount++;
                CheckTargetReached();
            }
            return Task.FromResult(0);
        }
    }

    [TestFixture]
    public class MassTransitTest
    {
        [Test]
        public async Task BasicTestAsync()
        {
            // Arrange
            var control = Bus.Factory.CreateUsingInMemory(configure =>
            {
                configure.ReceiveEndpoint("myQueue", endpoint =>
                {
                    endpoint.Consumer<MessageConsumer>();
                });
            });

            using (var handle = control.Start())
            {
                await handle.Ready; // [1]

                // Act
                await control.Publish(new Message());
                await control.Publish(new Message());

                // Assert
                MessageConsumer.TargetConsumedCount = 2;
                await MessageConsumer.TargetReached; // [2]
            }               
        }
    }
}