【发布时间】:2017-09-06 12:43:50
【问题描述】:
我正在尝试为 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();
}
}
在 SetMessagePriority 中正确抛出 ArgumentException 异常,因为“MessageType”等于 MessageType.Unknown。但是,在引发 ArgumentException 时,单元测试 EnqueueTest_UnknownMessageType 已成功通过,因为
var result = await _queue.EnqueueAsync(message);
在抛出异常之前返回“真”。 如何编写测试 EnqueueTest_UnknownMessageType 以使其因抛出异常而失败?
我已经尝试添加
[ExpectedException(typeof(ArgumentException))]
到测试,但它仍然通过
【问题讨论】:
-
这个例子看起来并不完整。提供可用于重现问题的minimal reproducible example。
-
一般
await _queue.EnqueueAsync(message);不太可能抛出您正在寻找的异常。在ActionBlock中捕获和抛出的任何异常都将附加到该块CompletionTask。这就是Task你需要await来观察异常。要说更多,您需要提供一个 MCVE,正如@Nkosi 指出的那样。 -
@Nkosi 这个例子是完整的。请告诉我您认为可能缺少什么
-
@Que,未显示单元测试正在调用的公共方法
EnqueueAsync()的实现。 -
@Eric,感谢您指出我已经更新了代码。为了简化我的问题,我不得不提取很多额外的代码,我想我错误地删除了该方法
标签: c# unit-testing asynchronous tpl-dataflow bufferblock