0

Now i'm working at writing unit test on azure service bus trigger function It's highly needed to mock somehow BrokeredMessage object that pass around into function. Function declaration is given below:

public static void Run(
            [ServiceBusTrigger("saas01.queue.dbmigration", AccessRights.Manage, Connection = "connection")]BrokeredMessage message)

Unfortunately, i can't find any applicable way to mock it. It hardly mocking du to this class is sealed and i can't event create wrapper around it. Do you have some ideas about it? Thanks for helping

,

Old Fox
  • 8,629
  • 4
  • 34
  • 52
MrTKer
  • 19
  • 5
  • 1
    Yeah it does seem to be a bit hard to create in such a way that it would act like a normal message. Would it work if you reduced the logic in the function into the smallest it can be, and just extract the message and necessary data from it. Then you can pass those to another class that you can unit test. – juunas Apr 27 '18 at 20:53
  • @MrTKer It seems to be a classic situation to use code weaving tools such as MsFakes, TypeMock Isolator and etc.. Do you have an access to any of them? – Old Fox Apr 28 '18 at 10:04
  • @OldFox No, i've never used any of them, it's based on reflection, right? – MrTKer Apr 28 '18 at 10:43
  • @MrTKer No, those to weave the code at the IL level to generate there mock. Since I'm not sure what you are trying to verify in your UT, I can't write an answer to your question *however* [this old answer of mine](https://stackoverflow.com/a/31899094/4332059) might help you to make decision with your current situation. – Old Fox Apr 28 '18 at 12:40

1 Answers1

2

One solution is to create a wrapper around BrokeredMessage you can test, as is done here. Here's also a MSDN post to the ServiceBus team that talks about using a wrapper too.

Note that Azure Functions V2 uses the Message class, which is public and not sealed.

    [FunctionName("ServiceBusFunc")]
    public static void Run([ServiceBusTrigger("myqueue", AccessRights.Manage, Connection = "ServiceBus")]BrokeredMessage myQueueItem, TraceWriter log)
    {
        var message = new MyBrokeredMessage(myQueueItem);
        BusinessLogic(message, log);
    }

    public static void BusinessLogic(MyBrokeredMessage myMessage, TraceWriter log)
    {
        var stream = myMessage.GetBody<Stream>();
        var reader = new StreamReader(stream);
        log.Info($"C# ServiceBus queue trigger function processed message: '{reader.ReadToEnd() }'");
    }

    public class MyBrokeredMessage
    {
        private BrokeredMessage _msg;

        public MyBrokeredMessage(BrokeredMessage msg) => _msg = msg;

        public T GetBody<T>()
        {
            return _msg.GetBody<T>();
        }
    }
Marie Hoeger
  • 1,261
  • 9
  • 11
  • You are wrong, learn more about Azure Func Service Bus trigger, over there in params of method pass around BrokeredMessage. – MrTKer Apr 28 '18 at 06:03
  • 1
    @MrTKer - I misspoke when I said that "`BrokeredMessage` is part of the ServiceBus SDK which isn't consumed by Azure Functions." I meant to get across that `BrokeredMessage` is from the ServiceBus SDK, but you are correct that the ServiceBusTrigger attribute "consumes" `BrokeredMessage` a parameter. Creating a wrapper around `BrokeredMessage` may still help you with unit testing if you can't test directly with `BrokeredMessage` objects as is done here: https://github.com/Azure-Samples/functions-unittesting-sample/blob/master/DotNet/DotNet.Test/QueueTriggerTest.cs – Marie Hoeger Apr 30 '18 at 22:18
  • Or here https://github.com/Azure/azure-webjobs-sdk/blob/v2.x/test/Microsoft.Azure.WebJobs.ServiceBus.UnitTests/MessageProcessorTests.cs – Marie Hoeger Apr 30 '18 at 22:18