繁体   English   中英

Azure Functions V2 的 MessageSender 单元测试

[英]Unit testing MessageSender for Azure Functions V2

我试图找到在我的 Azure 函数中使用 MessageSender 作为到 ServiceBus 的连接的最佳方法,以便对其进行单元测试。 我一直无法找到编写代码以对其进行单元测试的最佳方法。

代码

public static class SomeFunction
{        
    [FunctionName("SomeFunction")]
    public static async Task Run(
          [ServiceBusTrigger("someQueue", Connection = ConnectionString)]Message message
        , [ServiceBus("someQueue", Connection = ConnectionString")]MessageSender messagesQueue
        , MessageReceiver receiver
        , string lockToken)
    {
        ...some code
    }
}          

我试图将MessageSender更改为IMessageSender但出现以下绑定错误

绑定错误

System.InvalidOperationException: "Can't bind ServiceBus to type 'Microsoft.Azure.ServiceBus.Core.IMessageSender."

然后将其切换回MessageSender并尝试模拟它,一旦我运行测试,我就会收到以下错误。

单元测试示例

[TestMethod]
public async Task Run_ValidMessage_Expect_Run_Succesfully()
{
    var sbBuilder = new ServiceBusConnectionStringBuilder(ActualSbConnectionString);
    Mock<MessageSender>sender = new Mock<MessageSender>(sbBuilder, RetryPolicy.Default);
    SomeFunction.Run(_sender.Object);
}
Error: 
threw exception: 
    System.ArgumentException: The argument  is null or white space.
  Stack Trace: 
    at MessageSender.ctor(String entityPath, String transferDestinationPath, Nullable`1 entityType, ServiceBusConnection serviceBusConnection, ICbsTokenProvider cbsTokenProvider, RetryPolicy retryPolicy)
    at MessageSender.ctor(String connectionString, String entityPath, RetryPolicy retryPolicy)

我一直无法使用工作单元测试和函数编写代码。 任何指针都会有所帮助。

编辑:包括省略的参数

从您的代码来看,几乎没有错误,首先它应该是ServiceBusTrigger绑定而不是ServiceBus因为您没有显示触发器绑定或省略它。 然后,如果您的触发器是ServiceBusTrigger ,则只能绑定MessageReceiverMessageSender用于ServiceBus 示例代码

下面是我的测试代码,ServiceBusTrigger 接收消息,ServiceBus 发送消息。 我使用Microsoft.Azure.WebJobs.Extensions.ServiceBus 3.0.3

[FunctionName("Function1")]
    public static async System.Threading.Tasks.Task RunAsync([ServiceBusTrigger("myqueue", Connection = "ConnectionString")]
        MessageReceiver messageReceiver,
        ILogger log, 
        [ServiceBus("test", Connection = "ConnectionString")]MessageSender messagesQueue)
    {
        Console.Write(messageReceiver.Path);

        Message m1 = await messageReceiver.PeekAsync();

        await messagesQueue.SendAsync(m1);

    }

这对我有用,如果此代码是您想要的,您可以尝试一下。 如果您仍有问题,请随时告诉我。

聚会有点晚了,但我遇到了这个问题并找到了解决方法。

不是将MessageSender作为Run方法中的参数,而是将Func<MessageSender>注入到函数类中。

注意:我承认如果我可以在不需要采用这种方法的情况下进行单元测试可能会更好,但是我无法以任何其他方式让它工作......

例如

   public class SomeFunction
   {
      private readonly Func<IMessageSender> _messageSenderFactory;

      public SomeFunction(
         Func<IMessageSender> messageSenderFactory)
      {
         _messageSenderFactory = messageSenderFactory;
      }

      [FunctionName("SomeFunction")]
      public static async Task Run(
         [ServiceBusTrigger("someQueue", Connection = ConnectionString)]Message message,
         MessageReceiver receiver, 
         string lockToken)
      {
         // ...
         var messageSender = _messageSenderFactory.Invoke();
         await messageSender.SendAsync(message);
      }
   }

必须在 startup.cs 中为 DI 注册Func<IMessageSender>

         services.AddSingleton<Func<IMessageSender>>(() =>
            new MessageSender(Environment.GetEnvironmentVariable("SERVICE_BUS_CONNECTION"),
               Environment.GetEnvironmentVariable("someQueue")));

然后可以在单元测试中模拟Func<IMessageSender>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM