Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing MessageSender for Azure Functions V2

I am trying to find the best approach for using MessageSender in my Azure function as the connection to ServiceBus, in order to unit test it. I have been unable to find the best way to write my code to unit test it.

Code

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
    }
}          

I tried to change the MessageSender to IMessageSender but got the following binding error

Binding Error

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

Then switched it back to the MessageSender and tried mocking it and once I ran my test I got the error below.

Unit Test Example

[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)

I have been unable to write the code with a working unit test and function. any pointers would be helpful.

Edit: included omitted args

like image 648
Joe Jazdzewski Avatar asked Nov 29 '25 07:11

Joe Jazdzewski


1 Answers

From your code, there are few errors, firstly it should be ServiceBusTrigger binding not the ServiceBus cause you don't show your trigger bingding or you omit it. Then if your trigger is ServiceBusTrigger, you could only bind MessageReceiver, MessageSender is for ServiceBus. Sample code.

And the below is my test code, ServiceBusTrigger to receive the message, ServiceBus to send the message. I use the 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);

    }

This works for me, you could have a try if this code is what you want. If you still have problem, please feel free to let me know.

like image 63
George Chen Avatar answered Nov 30 '25 19:11

George Chen