我现在正在设计一些代码,如果字符串参数为null或为空,并且会按应有的方式引发异常,那么我将引发异常,但是在进行UnitTesting时不会被捕获。
这是我正在使用的客户端。
public class PipeClient : IPipeClient
{
public async void Send(string host, string pipeName, Message msg)
{
if (string.IsNullOrEmpty(msg.PreparedMessage))
throw new ArgumentException("MESSAGE_NOT_FOUND");
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(pipeName))
throw new ArgumentNullException();
if (!host.TryParseHost())
throw new ArgumentException("INVALID_HOST_NAME");
using (var pipeClient = new NamedPipeClientStream(host, pipeName, PipeDirection.Out))
{
pipeClient.Connect(200);
using (var writer = new StreamWriter(pipeClient))
{
await Task.Run(() => writer.WriteLine(msg.PreparedMessage));
writer.Flush();
}
}
}
}
这是UnitTest
[TestMethod]
public void Send_FailsOnWrongHostName()
{
var name = "FailWithHostname";
var msg = new Message(MyStates.Register, "UnitTest", "Test");
try
{
var client = new PipeClient();
client.Send("lol", name, msg);
}
catch (Exception e)
{
Assert.IsTrue(e is ArgumentException);
}
}
因此,当我运行该测试时,据我所知应该在调用Send方法(确实如此)时引发异常,然后由于未在PipeClient中捕获它而被catch子句捕获。但事实并非如此,它只是以失败的测试退出。
如果您需要更多信息,请提前告诉我。
答案 0 :(得分:2)
我想在这个答案中提出几点。我不确定您的经验水平,所以请不要以为我在任何时候都很自负。
首先简要介绍一下异步方法和任务。
“在观察到的任务中没有人可以尖叫” -Me,2018年
现在,如果这一切对您都没有意义,我建议您进行一些阅读,了解Tasks和async / await。
现在进入测试。
您的方法是异步无效的,因此没有任何调用方法可以返回给它来表示工作或让它知道该方法已引发异常。因此它继续进行,测试完成,然后一切正常完成,因为UnobservedTaskException可以在将来的任何时候抛出(我认为这与垃圾收集器整理有问题的Task的时间有关,然后抛出该异常,因为垃圾收集器是不确定的,我们无法确定何时会发生
那么,如果您使异步方法返回任务怎么办???嗯,这还不太正确。现在,由于异常,您将返回一个处于故障状态的任务,但是由于您从未等待过它,因此异常从未被“解包”并实际被抛出,因此您很高兴地进行了测试。
您需要做的是使您的测试异步并返回一个Task,并使正在测试异步的方法Task异步无效,然后在测试中等待该方法。
赞
[TestMethod]
public async Task Send_FailsOnWrongHostName()
{
var name = "FailWithHostname";
var msg = new Message(MyStates.Register, "UnitTest", "Test");
try
{
var client = new PipeClient();
await client.Send("lol", name, msg);
}
catch (Exception e)
{
Assert.IsTrue(e is ArgumentException);
}
}
public class PipeClient : IPipeClient
{
public async Task Send(string host, string pipeName, Message msg)
{
if (string.IsNullOrEmpty(msg.PreparedMessage))
throw new ArgumentException("MESSAGE_NOT_FOUND");
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(pipeName))
throw new ArgumentNullException();
if (!host.TryParseHost())
throw new ArgumentException("INVALID_HOST_NAME");
using (var pipeClient = new NamedPipeClientStream(host, pipeName, PipeDirection.Out))
{
pipeClient.Connect(200);
using (var writer = new StreamWriter(pipeClient))
{
await Task.Run(() => writer.WriteLine(msg.PreparedMessage));
writer.Flush();
}
}
}
}