MassTransit服务总线配置和单元测试

时间:2015-09-03 18:38:48

标签: unit-testing dependency-injection masstransit

对于MassTransit,在设置新的服务总线时,必须声明端点/类型;但是,我试图删除该依赖项,以便当我对消费者进行测试时,我可以利用环回端点但是一旦在生产中,它将使用实际的msmq端点。

以下是新服务总线的示例设置:

public class ConsumerService
{
    IServiceBus _bus;

    public void Start()
    {
        // Initalize Service Bus
        _bus = ServiceBusFactory.New(x =>
        {
            //x.UseMsmq();
            x.ReceiveFrom("loopback://localhost/MyQueue");
            x.SetConcurrentConsumerLimit(1);
        });
        _bus.SubscribeConsumer(() => new MyConsumer());
    }

    public void Stop()
    {
        _bus.Dispose();
    }
}

2 个答案:

答案 0 :(得分:3)

使用构造函数注入

public class ConsumerService
{
    private readonly IBusInitializer initializer;

    public ConsumerService(IBusInitializer initializer)
    {
        this.initializer = initializer;
    }

    IServiceBus _bus;

    public void Start()
    {
        // Initalize Service Bus
        _bus = ServiceBusFactory.New(x =>
        {
            this.initializer.initialize(x);
            x.SetConcurrentConsumerLimit(1);
        });
        _bus.SubscribeConsumer(() => new MyConsumer());
    }

    public void Stop()
    {
        _bus.Dispose();
    }
}

其中IInitializer是一个正确定义的接口,实现可能是:

public class LoopbackInitializer : IBusInitializer
{
    public void Initialize(WhateverXIs x)
    {
        x.ReceiveFrom("loopback://localhost/MyQueue");
    }
}

public class MsmqInitializer : IBusInitializer
{
    public void Initialize(WhateverXIs x)
    {
        x.UseMsmq();
    }
}

在测试中注入所需的实现或Composition Root

答案 1 :(得分:2)

我使用MassTransit启用测试的方法是在接口中封装服务总线的依赖关系,然后将此依赖项注入我的类中。

bus

的界面
public interface IPublishBus {
    void Publish<T>(T message) where T : class;
}

然后是生产中使用的实现

public class MassTransitBridge : IPublishBus {
    private IServiceBus _ServiceBus;
    private static readonly string __SubscriptionServiceQueue;
    private static readonly string __MassTransitBridgeQueue;

    static MassTransitBridge() {
        __SubscriptionServiceQueue = ConfigurationManager.AppSettings["mtSubscriptionService"];
        __MassTransitBridgeQueue = ConfigurationManager.AppSettings["mtBridgeQueue"];
    }

    public MassTransitBridge() {
        _ServiceBus = ServiceBusFactory.New(sbc => {
            sbc.UseMsmq(mq => {
                mq.UseSubscriptionService(__SubscriptionServiceQueue);
                mq.Configurator.UseControlBus();
                mq.Configurator.SetCreateTransactionalQueues(true);
            });
            sbc.DisablePerformanceCounters();
            sbc.ReceiveFrom(__MassTransitBridgeQueue);
            sbc.UseControlBus();
            sbc.UseJsonSerializer();
        });
    }

    public void Publish<T>(T message) where T : class {
        _ServiceBus.Publish<T>(message);
    }
}

在测试时,我使用注入我的服务的以下Mock对象

public class PublishBusMock : IPublishBus {
    public static List<Object> Messages { get; private set; }

    public PublishBusMock() {
        Messages = new List<object>();
    }

    public void Publish<T>(T message) where T : class {
        Messages.Add(message);      
    }

    public static void ClearMessages() {
        Messages = new List<object>();
    }
}

Mock对象允许我测试正在测试的object引发的正确消息。

同样以这种方式注入它可以让我在需要时替换实现MassTransit的其他内容{/ 1}}

相关问题