这是我的整个代码。我认为测试应该通过,但它失败了。我(尝试失败)试图将一些重载用于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工作?
答案 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]
}
}
}
}