Могу ли я получить серию хороших результатов и исключение из Moq - PullRequest
6 голосов
/ 12 июня 2009

Я высмеиваю оболочку MSMQ. Оболочка просто позволяет создать экземпляр объекта, который напрямую вызывает статические методы класса MessageQueue.

Я хочу проверить чтение очереди до исчерпания. Чтобы сделать это, я бы хотел, чтобы фиктивная оболочка возвращала некоторые хорошие результаты и генерировала исключение при четвертом вызове того же метода. Метод не принимает параметров и возвращает стандартный объект сообщения.

Могу ли я установить эту серию ожиданий для метода в Moq?

1 Ответ

5 голосов
/ 12 июня 2009

Да, это возможно, если вы не против перепрыгнуть через несколько мелких обручей. Я сделал это для одного из моих проектов раньше. Хорошо, вот основная техника. Я только что проверил это в Visual Studio 2008, и это работает:

var mockMessage1 = new Mock<IMessage>();
var mockMessage2 = new Mock<IMessage>();
var mockMessage3 = new Mock<IMessage>();

var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object });

var mockMsmqWrapper = new Mock<IMsmqWrapper>();

mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() =>
{
    if (messageQueue.Count == 0)
        mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<MyCustomException>();
});

Несколько заметок:

  1. Вам не нужно возвращать смоделированные сообщения, но это полезно, если вы также хотите проверить ожидания для каждого сообщения и посмотреть, были ли вызваны определенные методы или заданы свойства.
  2. Идея очереди не моя, просто подсказка, которую я получил из поста в блоге.
  3. Причина, по которой я генерирую исключение MyCustomException, заключается в том, что класс Queue автоматически генерирует исключение InvalidOperationException. Я хотел убедиться, что объект MsmqWrapper создает исключение из-за Moq, а не из-за того, что в очереди не осталось элементов.

Вот полный код, который работает. Имейте в виду, что этот код в некоторых местах ужасен, но я просто хотел показать вам, как это можно проверить:

public interface IMsmqWrapper
{
    IMessage GetMessage();
}

public class MsmqWrapper : IMsmqWrapper
{
    public IMessage GetMessage()
    {
        throw new NotImplementedException();
    }
}

public class Processor
{
    private IMsmqWrapper _wrapper;
    public int MessagesProcessed { get; set; }
    public bool ExceptionThrown { get; set; }

    public Processor(IMsmqWrapper msmqWrapper)
    {
        _wrapper = msmqWrapper;        
    }

    public virtual void ProcessMessages()
    {
        _wrapper.GetMessage();
        MessagesProcessed++;
        _wrapper.GetMessage();
        MessagesProcessed++;
        _wrapper.GetMessage();
        MessagesProcessed++;

        try
        {
            _wrapper.GetMessage();
        }
        catch (MyCustomException)
        {
            ExceptionThrown = true;
        }
    }
}

[Test]
public void TestMessageQueueGetsExhausted()
{
    var mockMessage1 = new Mock<IMessage>();
    var mockMessage2 = new Mock<IMessage>();
    var mockMessage3 = new Mock<IMessage>();

    var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object });

    var mockMsmqWrapper = new Mock<IMsmqWrapper>();
    mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() =>
    {
        if (messageQueue.Count == 0)
            mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<InvalidProgramException>();
    });

    var processor = new Processor(mockMsmqWrapper.Object);

    processor.ProcessMessages();

    Assert.That(processor.MessagesProcessed, Is.EqualTo(3));
    Assert.That(processor.ExceptionThrown, Is.EqualTo(true));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...