【问题标题】:How to use in memory transport with shared transport provider in MassTransit?如何在 MassTransit 中与共享传输提供程序一起使用内存传输?
【发布时间】:2020-03-06 16:07:34
【问题描述】:

我正在尝试遵循本指南以便能够创建一些功能测试:

https://masstransittemp.readthedocs.io/en/latest/configuration/transports/in_memory.html

问题是InMemoryTransportCache 类和SetTransportProvider 方法都不能被导入。我也找不到它们在 github 上的 MassTransit 源中声明。您如何实现顶部链接所描述的内容?

【问题讨论】:

  • 您正在查看非常旧的文档,您可以在此处找到内存中传输的当前文档:masstransit-project.com/usage/transports/in-memory.html。它没有提到传输缓存,它可能已被删除。也许您可以详细说明传输缓存的用例?
  • 我在功能测试中运行 2 个 asp.net core TestServer 实例(这都是一个进程)。我需要第一个服务器内的生产者Send 一个将由第二个服务器内的消费者处理的命令。目前,消费者类中的断点没有被击中。在调试模式下,我可以看到两条总线的地址不同。
  • 此外,消费者已正确注册,我知道,因为当我以标准方式运行应用程序时,该断点被命中。我也尝试在发布命令后添加Task.Delay(10000),但没有任何改变。
  • 无法使用共享内存结构创建两个总线实例。几个版本都不支持,可能要回v3/v4了。
  • @ChrisPatterson,出于好奇:你为什么要删除它?

标签: c# masstransit


【解决方案1】:

正如 cmets 中所述,您正在阅读的文档是无关紧要的。

以下是使用测试工具测试应用程序的方法:https://masstransit-project.com/usage/testing.html

基本上,无需启动测试服务器,除非您想测试您的注册。完成所有测试是一项相当繁重的工作。

文档提供了一个测试消费者的简短示例,所以我只是在这里复制粘贴:

public async Task Should_test_the_consumer()
{
    var harness = new InMemoryTestHarness();
    var consumerHarness = harness.Consumer<MyConsumer>();

    await harness.Start();
    try
    {
        await harness.InputQueueSendEndpoint.Send(new MyMessage());

        // did the endpoint consume the message
        Assert.IsTrue(harness.Consumed.Select<MyMessage>().Any());

        // did the actual consumer consume the message
        Assert.IsTrue(consumerHarness.Consumed.Select<MyMessage>().Any());
    }
    finally
    {
        await harness.Stop();
    }
}

测试工具的测试项目也有很多很好的例子:https://github.com/MassTransit/MassTransit/tree/develop/src/MassTransit.Tests/Testing

【讨论】:

  • 我无法使用测试工具。我正在写的是使用 Asp.Net Core 测试服务器的集成测试:visualstudiomagazine.com/articles/2017/07/01/testserver.aspx。这意味着对于我的解决方案所包含的每个 Web 应用程序项目,我正在启动 Asp.Net Core 测试服务器,以便我可以从上到下检查应用程序。我在这样的测试中检查了很多很多东西,其中之一是从上到下的消息处理。总结一下:这不是单元测试,而是集成测试,这就是我不使用测试工具的原因。
  • 我不知道你的拓扑结构,但是如果你有一个发送消息的 API 控制器,你只需要使用测试客户端调用那个 API 并检查结果。那里不需要内存中的传输,使用与生产中相同的传输,否则你永远不会说你的集成测试实际上测试了集成......
  • 需要内存中的传输,因为我希望我的测试也很快。我也想避免为这些测试设置整个 RabbitMQ 基础设施(+拆除)。也许我在使用“集成测试”这个术语时犯了一些术语错误,所以我会尝试清除它们。我正在检查系统不同部分的集成,但我认为不需要检查我是否真的正确设置了基础设施。我设法在我过去的一个项目中创建了这样一个(也许“功能性”是一个更好的词?)测试框架,我们证明它对我们来说已经足够了。
  • 我想在这里重复一遍,但我不记得我当时是怎么做到的......
  • 我不确定要设置什么。您需要做的就是运行 RMQ Docker 容器,然后停止它。我们一直这样做。图像下载完成后,大约需要 3 秒才能启动。
【解决方案2】:

正如 cmets 中所述 - 该文档已过时,但我的问题仍然有效。毕竟,我决定不采用为消息代理设置 Docker 容器的建议方法,而是使用测试工具(上面也建议)。我正在使用 SpecFlow,所以一般代码是在BeforeScenario 步骤中创建并启动线束,如下所示:

[BeforeScenario]
public async Task BeforeScenario() {
    _testHarness = new InMemoryTestHarness();

    await _testHarness.Start();
    TestStartup1.SetHarness(_testHarness);
    TestStartup2.SetHarness(_testHarness);

    // build WebHost and start both asp.net TestServer instances
}

[AfterScenario]
public async Task Cleanup() {
    await _testHarness.Stop();
}

并在两个测试启动中从线束中获取 IBusControl 实例:

// test startup1
public override void UseMassTransit(IServiceCollection services) {
    services.AddMassTransit(_ => {
        // configure endpoints here, etc.

        return _testHarness.BusControl;
    }, RegisterConsumers);
}

// test startup2
public override void UseMassTransit(IServiceCollection services) {
    services.AddMassTransit(_ => {
        // configure endpoints here, etc.

        _testHarness.Bus.ConnectReceiveEndpoint("your-endpoint", ep => ep.ConfigureConsumers(serviceProvider));

        return _testHarness.BusControl;
    }, RegisterConsumers);    
}

我还没有看到如何使消息处理同步,这样我就不必等待结果,但无论如何上面的代码解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-05
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多