How to mock Azure Queue storage for unit test?
Asked Answered
E

4

5

I want to mock QueueMessage for unit test,but I can not find any lib to mock

    public  async Task<QueueMessage[]> ReceiveMessagesAsync(QueueClient queue)
       {
     
        QueueProperties properties = queue.GetProperties();

        // Retrieve the cached approximate message count.
        int cachedMessagesCount = properties.ApproximateMessagesCount;
        QueueMessage[] queueMessages =new QueueMessage[cachedMessagesCount];

        int num = cachedMessagesCount / 32;

        for (int i = 0; i < num + 1; i++)
        {
         var  messages = await queue.ReceiveMessagesAsync(maxMessages: 32);
         messages.Value.CopyTo(queueMessages,i*32);
        }
        return queueMessages;
    }
Eldest answered 7/8, 2020 at 9:12 Comment(2)
What is the point of mocking aspects of an EAI System? A message is just the envelope. You want the payload. Wouldn't it instead be better to test the handler for the payload. A well-written system should have its business logic de-coupled from any EAI systemBax
@MickyD thank you for your comment! You really got a point there and I solved this unneeded issue by just returning QueueMessage.MessageText instead of the object itself. Absolutely true point which needs to be considered!Eloquence
P
6

The constructors of the Queue models are internal, but you can create objects using the QueuesModelFactory which provides utilities for mocking.

QueueMessage queueMsg = QueuesModelFactory.QueueMessage(
    messageId: "id2", 
    popReceipt: "pr2", 
    body: JsonConvert.SerializeObject("Test"), 
    dequeueCount: 1, 
    insertedOn: DateTimeOffset.UtcNow);

 var metadata = new Dictionary<string, string> { { "key", "value" }, };
 int messageCount = 5;
 QueueProperties queueProp = QueuesModelFactory.QueueProperties(metadata, messageCount);
Ploughboy answered 9/9, 2021 at 8:54 Comment(0)
I
3

Choice of Mocking lib would be an opinionated answer. There are several mocking frameworks available. One of the popular ones is Moq.

Using Moq, the sample test for your above code would look like below. Note that mocking storage lib is a bit tedious task as you can see.

        [Test]
        public async Task ReceiveMessagesAsync_StateUnderTest_ExpectedBehavior()
        {
            // Arrange
            var queueClientHelper = new QueueClientHelper();
            var queueMock = new Mock<QueueClient>();
            var mockPropertiesResponse = new Mock<Response<QueueProperties>>();
            var properties = new QueueProperties();
            properties.GetType().GetProperty(nameof(properties.ApproximateMessagesCount), BindingFlags.Public | BindingFlags.Instance).SetValue(properties, 64); // little hack since ApproximateMessagesCount has internal setter
            mockPropertiesResponse.SetupGet(r => r.Value).Returns(properties);
            queueMock.Setup(q => q.GetProperties(It.IsAny<CancellationToken>())).Returns(mockPropertiesResponse.Object);
            var mockMessageReponse = new Mock<Response<QueueMessage[]>>();
            mockMessageReponse.SetupGet(m => m.Value).Returns(new QueueMessage[32]);
            queueMock.Setup(q => q.ReceiveMessagesAsync(It.IsAny<int?>(), It.IsAny<TimeSpan?>(), It.IsAny<CancellationToken>())).ReturnsAsync(mockMessageReponse.Object);

            // Act
            var result = await queueClientHelper.ReceiveMessagesAsync(queueMock.Object);

            // Assert
            Assert.AreEqual(64, result.Length);
            // verify mocks as required
        }
Inexpressive answered 12/8, 2020 at 18:31 Comment(1)
Thank u so much!GhoshEldest
C
1

Try to mock the response of queueClient this will verify sendMessageAsync response

[Fact]
    public async Task SendMessage_ShouldReturnSuccess()
    {
        var receipt = QueuesModelFactory.SendReceipt("1", DateTimeOffset.Now, DateTimeOffset.Now.AddDays(2), "pop", DateTimeOffset.Now.AddDays(1));
        var res = Response.FromValue<SendReceipt>(receipt, null);
        var queueClientmock = new Mock<QueueClient>();
        queueClientmock.Setup(q => q.SendMessageAsync(It.IsAny<string>())).Returns(Task.FromResult(res));
        var sqmock = new Mock<IStorageQueueProvider>();
        sqmock.Setup(s => s.GetStorageQueueClient()).Returns(Task.FromResult(queueClientmock.Object)).Verifiable();
        var storageQueueRepository = new StorageQueueRepository(sqmock.Object, DummyLogger);
        var result = await storageQueueRepository.SendMessage("test message");
        result.StatusCode.Should().Be(HttpStatusCode.OK);
    }
Clown answered 2/12, 2021 at 4:56 Comment(0)
C
1
        return QueuesModelFactory.QueueMessage(
            messageId: "id2",
            popReceipt: "pr2",
            body: BinaryData.FromString(encode ? Convert.ToBase64String(Encoding.UTF8.GetBytes(Message)) : Message),
            dequeueCount: dequeueCount,
            insertedOn: DateTimeOffset.UtcNow);
Caines answered 31/1, 2023 at 17:8 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Leaving

© 2022 - 2024 — McMap. All rights reserved.