我在测试中有一个奇怪的行为,我想测试当作为参数传入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);
}
}
}
这种行为是否有合理的解释,我应该以不同的方式进行实施吗?
答案 0 :(得分:9)
您获得此行为的原因是yield关键字。使用yield时,编译器将为该方法生成一个类,其中包含yield。调用该方法时,无条件地将控制权返回给调用者。在您需要之前,您的方法中没有任何内容实际执行。
如果将using语句提取到单独的方法中并返回结果,则测试将通过。或者您可以将结果存储到测试中的变量中,例如在其上调用“ToList()”。
public IEnumerable<ImportField> CreateFields(HttpPostedFileBase file)
{
if (file == null) throw new ArgumentNullException("file");
return ExtractFromFile(file);
}
private IEnumerable<ImportField> ExtractFromFile(HttpPostedFileBase 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);
}
}
}