我正在尝试为TPL BufferBlock创建单元测试,并希望测试是否抛出异常。但是,测试在异常被抛出之前传递。
修改
此外,这是一个漫长的过程,所以我不打电话给完成。此过程一直运行直到应用程序关闭
以下是代码:
public class PriorityMessageQueue
{
private BufferBlock<MyMessage> _messageBufferBlock;
private async Task<bool> Init()
{
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount,
BoundedCapacity = 1000
};
var prioritizeMessageBlock = new ActionBlock<MyMessage>(msg =>
{
try
{
SetMessagePriority(msg);
}
catch (Exception)
{
throw;
}
});
_messageBufferBlock = new BufferBlock<MyMessage>(executionDataflowBlockOptions);
_messageBufferBlock.LinkTo(prioritizeMessageBlock);
}
public async Task<bool> EnqueueAsync(MyMessage message)
{
if (message == null)
{
throw new ArgumentNullException(nameof(message), "The message object is NULL. Cannot enqueue a NULL object.");
}
return await _messageBufferBlock.SendAsync(message);
}
private void SetMessagePriority(MyMessage message)
{
if (message.MessageType.Equals(MessageType.Unknown))
{
throw new ArgumentException("The SCBA Message Type is 'Unknown'. Cannot set the Message Priority on an 'Unknown' message type.");
}
switch (message.MessageType)
{
case MessageType.Admin:
message.MessagePriority = MessagePriority.Admin;
break;
case MessageType.AuthUser:
message.MessagePriority = MessagePriority.High;
break;
case MessageType.UnknownUser:
message.MessagePriority = MessagePriority.Normal;
break;
default:
message.MessagePriority = MessagePriority.Normal;
break;
}
}
}
这是测试代码
[TestClass()]
public class PriorityMessageQueueTests
{
private IPriorityMessageQueue _queue;
[TestInitialize]
public void Init()
{
IUnityContainer container = new UnityContainer();
var logRepository = new Mock<ILogRepository>();
container.RegisterInstance(logRepository.Object);
_queue = new PriorityMessageQueue(logRepository.Object);
}
[TestCleanup]
public void CleanUp()
{
_queue.Dispose();
}
[TestMethod()]
[ExpectedException(typeof(ArgumentNullException))]
public async Task EnqueueTest_NullMessage()
{
await _queue.EnqueueAsync(null);
}
[TestMethod()]
public async Task EnqueueTest_UnknownMessageType()
{
var message = new MyMessage
{
Id = 1,
Text = "Unit Test"
};
var result = await _queue.EnqueueAsync(message);
Assert.AreEqual(true, result);
}
[TestMethod()]
public void DequeueTest()
{
Assert.Fail();
}
[TestMethod()]
public void GetNextInQueue()
{
Assert.Fail();
}
}
ArgumentException异常在SetMessagePriority中被正确抛出,因为&#39; MessageType&#39;等于MessageType.Unknown。但是,在抛出ArgumentException时,单元测试EnqueueTest_UnknownMessageType已成功通过,因为
var result = await _queue.EnqueueAsync(message);
返回&#39; true&#39;在异常被抛出之前。 如何编写测试EnqueueTest_UnknownMessageType以使其失败,因为抛出了异常?
我尝试过添加
[ExpectedException(typeof(ArgumentException))]
进行测试,但仍然通过
答案 0 :(得分:0)
正如@JSteward指出的那样,您期望看到的例外不会成为您在Task
方法中等待的EnqueueAsync()
的一部分。
通过docs for DataflowBlock.SendAsync()
阅读以下有关返回值的内容:
如果目标在调用
SendAsync
期间接受并使用提供的元素,则在从调用返回时,生成的Task<TResult>
将完成,其Result
属性将返回{{1} }}。如果目标在通话期间拒绝提供的元素,则在通过通话返回时,结果true
将完成,其Task<TResult>
属性将返回Result
。
false
仅表示第一个块收到或拒绝了该消息。没有提及将后续块中的异常传播回原始Task
。
如果您正在寻找对消息类型的早期验证,您可以在Task
调用中进行检查,从数据流管道中删除该块。
否则,如果您希望这是更大的数据流管道中的一个步骤,您可以注入一个BroadcastBlock<T>
,您可以附加其余的&#34;快乐路径&#34;用于处理已知消息类型的管道以及仅接收未知消息类型的块,您可以在其中接收要通信的任何操作,并收到未知消息类型。