【问题标题】:Unit testing for a publish method in mass transit using in memory bus使用内存总线对公共交通中的发布方法进行单元测试
【发布时间】:2016-06-06 18:09:39
【问题描述】:

我是 MassTransit 和消息传递的新手。我正在尝试为 IBus.Publish 编写单元测试,但无法获得成功。

我正在观察 RabbitMQ 的故障,我的观察者看起来像这样:

public class FaultObserver : IReceiveObserver
{
    public FaultObserver(IRequestUpdater statusUpdater,Lazy<IBus> bus)
    {
        this.statusUpdater = statusUpdater;
        this.bus = bus;
    }

    public async Task ConsumeFault<T>(ConsumeContext<T> context, TimeSpan                                    duration, string consumerType, Exception exception) where T : class
    {
    }
 }

我的测试看起来像下面的代码

var bus = fixture.Freeze<Mock<IBus>>();

bus.Setup(bu => bu.Publish<ReportFailedEvent>(It.IsAny<ReportFailedEvent>(),It.IsAny<CancellationToken>())).Verifiable();

var sut = fixture.Create<ReportRequestedFaultObserver>();
// Act
await sut.ConsumeFault(context.Object,new TimeSpan(0,0,1),string.Empty,exception);

// Assert
//bus.Verify(b => b.Publish<ReportFailedEvent>(It.IsAny<ReportFailedEvent>(), It.IsAny<CancellationToken>()), Times.Exactly(1));
bus.Verify(b =>b.Publish<ReportFailedEvent>(new ReportFailedEvent(request,exception.Message),It.IsAny<CancellationToken>()),Times.Once());

我的设置看起来像

[SetUp]
public void SetUp()
{
    fixture.Customize(new AutoMoqCustomization());
    var inMemoryTransportCache = new InMemoryTransportCache(Environment.ProcessorCount);

    bus = Bus.Factory.CreateUsingInMemory(configure =>
    {
        configure.SetTransportProvider(inMemoryTransportCache);
        configure.ReceiveEndpoint("input_queue", configurator => 
        { 
            configurator.Handler<(cc => 
            {
            });
        }); 

    });

    bus.Start().Ready.Wait();
}

我无法模拟我的 Publish 方法。有谁知道我做错了什么?

【问题讨论】:

  • 您应该从ConsumeContext 发布,而不是从IBus - 永远不应该将IBus 注入您的观察者。
  • 感谢您的快速回复。我会尽力让您知道
  • 你好,克里斯,我已经实现了 context.publish,我从我的 oberver 中取出了 DI,但我的单元测试仍然失败。
  • 好吧,我无法解释你的单元测试我不使用模拟。您可以查看 MassTransit 单元测试以了解如何检查预期。没有嘲笑。
  • 你有我可以关注的链接吗?

标签: rabbitmq masstransit


【解决方案1】:

您对公共汽车的模拟是错误的。应该是:

bus.Setup(bu => bu.Publish<ReportFailedEvent>(
    It.IsAny<object>(), It.IsAny<CancellationToken>()));

根据 MassTransit 中的接口定义,Publish 采用 objectCancellationToken

Task Publish(object message, CancellationToken cancellationToken = default(CancellationToken));

另外,如果你想查看消息的内容,你可以使用 Moq Callback 扩展:

ReportFailedEvent message = null;
bus
  .Setup(bu => bu.Publish<ReportFailedEvent>(It.IsAny<object>(), It.IsAny<CancellationToken>()))
  .Callback<object, CancellationToken>((a, b) => { message = a as ReportFailedEvent; });

//.. your system under test code....

Assert.That(message.Property, Is.EqualTo(expectation));

如果您设置优先级,MassTransit 界面如下所示:

public static Task Publish<T>(
      this IPublishEndpoint endpoint,
      T message,
      Action<PublishContext<T>> callback,
      CancellationToken cancellationToken = default(CancellationToken))
      where T : class;

举个例子:

bus.Publish<ReportFailedEvent>(message, context =>
{
    context.SetPriority(messagePriority.Priority);
});

附带的起订量是:

ReportFailedEvent message = null;
bus
  .Setup(bu => bu.Publish<ReportFailedEvent>(It.IsAny<object>(), It.IaAny<Action<PublishContext<ReportFailedEvent>>>(), It.IsAny<CancellationToken>()))
  .Callback<object, Action<PublishContext<ReportFailedEvent>>, CancellationToken>((a, b, c) => { message = a as ReportFailedEvent; });

顺便说一句,理想情况下,您应该发布接口而不是类,所以IReportFailedEvent 而不是ReportFailedEvent

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多