繁体   English   中英

如何模拟 Azure 单元测试的队列存储?

[英]How to mock Azure Queue storage for unit test?

我想模拟 QueueMessage 进行单元测试,但我找不到任何 lib 来模拟

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

选择 Mocking lib 将是一个固执的答案。 有几个 mocking 框架可用。 最受欢迎的之一是Moq

使用 Moq,上述代码的示例测试如下所示。 请注意,如您所见,mocking 存储库是一个有点乏味的任务。

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

队列模型的构造函数是内部的,但您可以使用为mocking提供实用程序的 QueuesModelFactory 创建对象。

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

尝试模拟 queueClient 的响应,这将验证 sendMessageAsync 响应

[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);
    }
        return QueuesModelFactory.QueueMessage(
            messageId: "id2",
            popReceipt: "pr2",
            body: BinaryData.FromString(encode ? Convert.ToBase64String(Encoding.UTF8.GetBytes(Message)) : Message),
            dequeueCount: dequeueCount,
            insertedOn: DateTimeOffset.UtcNow);

暂无
暂无

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

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