C# 在Azure服务总线中发布到某个主题并订阅另一个主题的集成测试不可靠是否存在竞争条件?

C# 在Azure服务总线中发布到某个主题并订阅另一个主题的集成测试不可靠是否存在竞争条件?,c#,unit-testing,azure,message-queue,azure-servicebus-topics,C#,Unit Testing,Azure,Message Queue,Azure Servicebus Topics,我正在尝试编写一个集成/验收测试来测试azure中的一些代码,ATM问题中的代码只是订阅一个主题并发布到另一个主题 我写了测试,但它并不总是通过,似乎有可能是一个种族条件的地方。我尝试了几种方法来编写它,包括使用OnMessage和Receive(我在这里展示的示例) 当使用OnMessage时,测试似乎总是过早退出(大约30秒),我想这可能意味着它无论如何都不适合这个测试 关于我的示例,我的问题是,我假设,一旦我创建了对目标主题的订阅,发送给它的任何消息都可以使用Receive()拾取,无论消

我正在尝试编写一个集成/验收测试来测试azure中的一些代码,ATM问题中的代码只是订阅一个主题并发布到另一个主题

我写了测试,但它并不总是通过,似乎有可能是一个种族条件的地方。我尝试了几种方法来编写它,包括使用OnMessage和Receive(我在这里展示的示例)

当使用OnMessage时,测试似乎总是过早退出(大约30秒),我想这可能意味着它无论如何都不适合这个测试

关于我的示例,我的问题是,我假设,一旦我创建了对目标主题的订阅,发送给它的任何消息都可以使用Receive()拾取,无论消息到达的时间点是什么,如果消息在我调用Receive()之前到达目标主题,之后我仍然可以通过调用Receive()来阅读消息。有人能解释一下吗

    namespace somenamespace {
    [TestClass]
    public class SampleTopicTest
    {
        private static TopicClient topicClient;
        private static SubscriptionClient subClientKoEligible;
        private static SubscriptionClient subClientKoIneligible;

        private static OnMessageOptions options;
        public const string TEST_MESSAGE_SUB = "TestMessageSub";
        private static NamespaceManager namespaceManager;

        private static string topicFleKoEligible;
        private static string topicFleKoIneligible;

        private BrokeredMessage message;

        [ClassInitialize]
        public static void BeforeClass(TestContext testContext)
        {
            //client for publishing messages
            string connectionString = ConfigurationManager.AppSettings["ServiceBusConnectionString"];
            string topicDataReady = ConfigurationManager.AppSettings["DataReadyTopicName"];
            topicClient = TopicClient.CreateFromConnectionString(connectionString, topicDataReady);

            topicFleKoEligible = ConfigurationManager.AppSettings["KnockOutEligibleTopicName"];
            topicFleKoIneligible = ConfigurationManager.AppSettings["KnockOutIneligibleTopicName"];

            //create test subscription to receive messages
            namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);


            if (!namespaceManager.SubscriptionExists(topicFleKoEligible, TEST_MESSAGE_SUB))
            {
                namespaceManager.CreateSubscription(topicFleKoEligible, TEST_MESSAGE_SUB);
            }

            if (!namespaceManager.SubscriptionExists(topicFleKoIneligible, TEST_MESSAGE_SUB))
            {
                namespaceManager.CreateSubscription(topicFleKoIneligible, TEST_MESSAGE_SUB);
            }

            //subscriber client koeligible
            subClientKoEligible = SubscriptionClient.CreateFromConnectionString(connectionString, topicFleKoEligible, TEST_MESSAGE_SUB);

            subClientKoIneligible = SubscriptionClient.CreateFromConnectionString(connectionString, topicFleKoIneligible, TEST_MESSAGE_SUB);

            options = new OnMessageOptions()
            {
                AutoComplete = false,
                AutoRenewTimeout = TimeSpan.FromMinutes(1),

            };
        }

          [TestMethod]
        public void E2EPOCTopicTestLT50()
        {
            Random rnd = new Random();
            string customerId = rnd.Next(1, 49).ToString();

            FurtherLendingCustomer sentCustomer = new FurtherLendingCustomer { CustomerId = customerId };
            BrokeredMessage sentMessage = new BrokeredMessage(sentCustomer.ToJson());           
            sentMessage.CorrelationId = Guid.NewGuid().ToString();
            string messageId = sentMessage.MessageId;
            topicClient.Send(sentMessage);

            Boolean messageRead = false;

            //wait for message to arrive on the ko eligible queue
            while((message = subClientKoEligible.Receive(TimeSpan.FromMinutes(2))) != null){

                //read message
                string messageString = message.GetBody<String>();

                //Serialize
                FurtherLendingCustomer receivedCustomer =  JsonConvert.DeserializeObject<FurtherLendingCustomer>(messageString.Substring(messageString.IndexOf("{")));

                //assertion
                Assert.AreEqual(sentCustomer.CustomerId, receivedCustomer.CustomerId,"verify customer id");

                //pop message
                message.Complete();
                messageRead = true;

                //leave loop after processing one message
                break;
            }
            if (!messageRead)
                Assert.Fail("Didn't receive any message after 2 mins");

        }
    }
}
名称空间{
[测试类]
公共类抽样测验
{
私有静态TopicClient TopicClient;
私有静态订阅客户端子客户端;
私有静态订阅客户端子客户端不合格;
私有静态OnMessageOptions;
public const string TEST_MESSAGE_SUB=“TestMessageSub”;
私有静态名称空间管理器名称空间管理器;
私有静态字符串topicfleko;
私有静态字符串主题不合格;
私人代理消息;
[分类初始化]
公共静态void BeforeClass(TestContext TestContext)
{
//用于发布消息的客户端
string connectionString=ConfigurationManager.AppSettings[“ServiceBusConnectionString”];
字符串topicDataReady=ConfigurationManager.AppSettings[“DataReadyTopicName”];
topicClient=topicClient.CreateFromConnectionString(connectionString,topicDataReady);
TopicFlekoQualified=ConfigurationManager.AppSettings[“KnockOutEligibleTopicName”];
TopicFlekoInqualible=ConfigurationManager.AppSettings[“knockoutieGibleTopicName”];
//创建测试订阅以接收消息
namespaceManager=namespaceManager.CreateFromConnectionString(connectionString);
如果(!namespaceManager.SubscriptionExists(topicflekoqualified,TEST_MESSAGE_SUB))
{
namespaceManager.CreateSubscription(topicflekoqualified,TEST_MESSAGE_SUB);
}
如果(!namespaceManager.SubscriptionExists(TopicFlekoInqualifible,TEST_MESSAGE_SUB))
{
namespaceManager.CreateSubscription(TopicFleKoInqualible,测试消息子文件);
}
//订户客户端
subclientkoqualify=SubscriptionClient.CreateFromConnectionString(connectionString,TopicFlekoqualify,TEST\u MESSAGE\u SUB);
SubclientkoInqualible=SubscriptionClient.CreateFromConnectionString(connectionString,TopicFlekoInqualible,TEST\u MESSAGE\u SUB);
选项=新的OnMessageOptions()
{
自动完成=错误,
AutoRenewTimeout=时间跨度从分钟(1),
};
}
[测试方法]
公共空间E2EPOCTopicTestLT50()
{
随机rnd=新随机();
字符串customerId=rnd.Next(1,49).ToString();
FutureLendingCustomer sentCustomer=新的FutureLendingCustomer{CustomerId=CustomerId};
BrokeredMessage sentMessage=新的BrokeredMessage(sentCustomer.ToJson());
sentMessage.CorrelationId=Guid.NewGuid().ToString();
字符串messageId=sentMessage.messageId;
topicClient.Send(sentMessage);
布尔messageRead=false;
//等待消息到达符合条件的队列
while((message=subclientkoqualified.Receive(TimeSpan.frommins(2)))!=null){
//阅读信息
string messageString=message.GetBody();
//连载
FutureLendingCustomer-receivedCustomer=JsonConvert.DeserializeObject(messageString.Substring(messageString.IndexOf(“{”));
//断言
Assert.AreEqual(sentCustomer.CustomerId、receivedCustomer.CustomerId,“验证客户id”);
//流行语
message.Complete();
messageRead=true;
//处理一条消息后离开循环
打破
}
如果(!messageRead)
Assert.Fail(“2分钟后没有收到任何消息”);
}
}
}

正如官方文件所述:

参数 serverWaitTime 时间跨度

服务器在超时之前等待接收消息的时间跨度

如果操作超过了指定的超时时间,或者操作成功但没有更多的消息要接收,则此API可以返回Null

根据我的测试,如果消息发送到主题,然后在特定的serverWaitTime内发送到您的订阅,那么无论消息是在您调用
receive
之前还是之后到达目标主题,您都可以收到消息

当使用OnMessage时,测试似乎总是过早退出(大约30秒),我想这可能意味着它无论如何都不适合这个测试

[TestMethod]
public void ReceiveMessages()
{
subClient.OnMessage(消息=>{
System.Diagnostics.Trace.TraceInformation($“{DateTime.Now}:{msg.GetBody()}”);
msg.Complete();
});
Task.Delay(TimeSpan.frommins(5)).Wait();
}

因为,我假设它基本上是一个
[TestMethod]
public void ReceiveMessages()
{
    subClient.OnMessage(msg => {
        System.Diagnostics.Trace.TraceInformation($"{DateTime.Now}:{msg.GetBody<string>()}");
        msg.Complete();
    });
    Task.Delay(TimeSpan.FromMinutes(5)).Wait();
}