NUnit中的奇怪行为,ExpectedException和yield return

9

我在一个测试中遇到了奇怪的行为,我想测试传递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);
        }
    }
}

有没有一种逻辑上的解释来解释这种行为,我是否应该以不同的方式进行实现?
1个回答

10
你遇到这种情况是因为使用了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);
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接