NUnit、ExpectedException 和 NUnit 的奇怪行为收益率回报
我在测试中有一个奇怪的行为,我想测试当 null 作为参数传入时是否引发异常。当我运行测试时,我从 NUnit 得到:
System.ArgumentNullException was expected
-- Exception doesn't have a stack trace --
我的测试:
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Should_not_retrieve_any_fields_when_file_is_null()
{
_creator.CreateFields(null);
}
我的实现:
public IEnumerable<ImportField> CreateFields(HttpPostedFileBase file)
{
if (file == null) throw new ArgumentNullException("file");
using (var reader = new StreamReader(file.InputStream))
{
var firstLine = reader.ReadLine();
var columns = firstLine.Split(new[] { ',' });
for (var i = 0; i < columns.Length; i++)
{
yield return new ImportField(columns[i], i);
}
}
}
此行为是否有逻辑解释,我应该以不同的方式实现我的实现吗?
I have a strange behavior in a tests where I want to test that an exception is thrown when null is passed in as a parameter. When I run the test I get from NUnit:
System.ArgumentNullException was expected
-- Exception doesn't have a stack trace --
My test:
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Should_not_retrieve_any_fields_when_file_is_null()
{
_creator.CreateFields(null);
}
My implementation:
public IEnumerable<ImportField> CreateFields(HttpPostedFileBase file)
{
if (file == null) throw new ArgumentNullException("file");
using (var reader = new StreamReader(file.InputStream))
{
var firstLine = reader.ReadLine();
var columns = firstLine.Split(new[] { ',' });
for (var i = 0; i < columns.Length; i++)
{
yield return new ImportField(columns[i], i);
}
}
}
Is there a logical explanation to this behavior and should I make my implementation differently?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您出现此行为的原因是yield 关键字。当使用yield时,编译器会为包含yield的方法生成一个类。当调用该方法时,控制权将无条件返回给调用者。您的方法中的任何内容在需要之前都不会实际执行。
如果将 using 语句提取到单独的方法中并返回结果,则测试将通过。或者您可以将结果存储到测试中的变量中,例如对其调用“ToList()”。
The reason you're getting this behaviour is because of the yield keyword. When using yield, the compiler will generate a class for the method with the yield in it. When calling that method, control is unconditionally returned to back to the caller. Nothing in your method is actually executed before it is need.
If you extract your using statement into a separate method and return the result, your test will pass. Or you can store the result to a variable in your test, and for example call "ToList()" on it.