是的,如果你不介意跳过几个小圈圈,这是可能的。我以前为我的一个项目做过这个。好的,这是基本的技术。我刚在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>();
});
几点注意事项
-
您不必返回模拟消息,但如果您想验证每个消息的期望值,以及查看是否调用了某些方法或是否设置了属性,则返回模拟消息非常有用。
-
排队不是我自己的主意,只是我从一篇博文中得到的提示。
-
我引发MyCustomException异常的原因是队列类自动引发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));
}