Moq проверить, что указанное c исключение выбрасывается и перехватывается - PullRequest
1 голос
/ 30 января 2020

У меня есть метод для создания очереди при необходимости. Если очередь уже существует, метод возвращает значение false, если создание прошло успешно.

Я хотел бы проверить сценарий, когда очередь не существует во время проверки QueueExists, но создается другой перед тем, как приступить к вызову CreateQueueAsync.

У меня есть код продукта:

internal bool QueueExists(string queueName)
{
    var allQueues = ManagementClient.GetQueuesAsync().Result;
    if (!allQueues.Any(q => q.Path.Equals(queueName)))
    {
        return false;
    }
    return true;
}
public bool CreateQueueIfNotExists(string queueName, bool requiresSession)
{
    if (!QueueExists(queueName))
    {
        try
        {
            ManagementClient.CreateQueueAsync(queueDescription).Wait();
            return true;
        }
        catch (AggregateException ae)
        {
            Exception e = ae.GetBaseException();

            // If the queue already exists then no additional action is needed.
            if (e is MessagingEntityAlreadyExistsException)
            {
                return false;
            }
            else
            {
                ExceptionDispatchInfo.Throw(e);
            }
        }
    }
    else
    {
        return false;
    }
}

Мой тест Nunit CreateQueueAsync будет вызван дважды, потому что GetQueuesAsync всегда будет возвращаться пустой список.

[Test]
public void QueueCreation_MessagingEntityAlreadyExistsException_IsCatched()
{
    // Given            
    var managementClientMock = new Mock<ManagementClient>(connectionString) { CallBase = true };
    managementClientMock.Setup(m => m.GetQueuesAsync(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<System.Threading.CancellationToken>()))
        .Returns(Task.FromResult<IList<QueueDescription>>(new List<QueueDescription>()));
    QueueFactory queueFactory = new QueueFactory(managementClientMock.Object);

    Assert.That(queueFactory.CreateQueueIfNotExists(alreadyExistsQueue, true), Is.True, 
"First queue creation did not returned true.");
    Assert.That(queueFactory.CreateQueueIfNotExists(alreadyExistsQueue, true), Is.False, 
"First queue creation did not returned false.");
    managementClientMock.Verify(m => m.CreateQueueAsync(It.IsAny<QueueDescription>(), It.IsAny<System.Threading.CancellationToken>()), Times.Exactly(2));
}

Это нормально, но я хочу проверить, генерируется ли исключение агрегации И ПОВТОРЯЕТСЯ ли во второй раз, а MessagingEntityAlreadyExistsException является внутренним исключением. Так что ExpectedException и Assert.Throws не будут работать здесь, исключение поймано в методе продукта.

Есть ли способ сделать это с Moq?

1 Ответ

0 голосов
/ 09 февраля 2020

Интересный вопрос - я ничего не знаю в Moq, который делает это. Однако можете ли вы получить то, что вы ищете, разделив проблему на две части (извините, если я неправильно понял)?

Сначала, отдельно протестируйте ManagementClient, убедитесь, что при повторном вызове с одной и той же очередью агрегатное исключение, и это MessagingEntityAlreadyExistsException является внутренним исключением.

Во-вторых, протестируйте код, принадлежащий методу в вашем примере, с заглушкой ManagementClient, которая выдает агрегатное исключение, содержащее то же самое внутреннее исключение при вызове. В этом тесте убедитесь, что не было сгенерировано исключение (т. Е. Исключение было перехвачено и не было переброшено).

...