NUniteLite 3.11.0在LINQpad中使用AutoRun引发Null参考异常

时间:2018-10-18 22:55:15

标签: c# nunit linqpad nunit-3.0

以下LINQPad查询在try-catch块中抛出NullReferenceException

void Main()
{
    var specialFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
    var workingFolder = $@"{specialFolder}\NUnitLiteTestResults";
    var args = new[]
        {
            "--labels=All",
            "--nocolor",
            "--noheader",
            $"--work={workingFolder}"
        };

    try
    {
        (new AutoRun()).Execute(args);
    }
    catch (NullReferenceException ex)
    {
        ex.Dump("why?");
    }
}

public class Runner
{
    /*
        public static int Main(string[] args) {
            return new AutoRun(Assembly.GetCallingAssembly()).Execute(new String[] {"--labels=All"});
        }
    */
    [TestFixture]
    public class FooTest
    {
        [Test]
        public void ShouldCheckBoolean()
        {
            Assert.IsTrue(true);
        }

        [Test]
        public void ShouldCompareNumbers()
        {
            Assert.AreEqual(2, 2);
        }

        [Test]
        public void ShouldCompareStrings()
        {
            Assert.AreEqual("abc", "abc");
        }

        [Test]
        public void TestCompareLists()
        {
            Assert.AreEqual(new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 });
        }
    }
}

我在这里丢失任何设置代码吗?

异常(我的计算机上没有C:\src\nunit文件夹):

Object reference not set to an instance of an object.
 at System.IO.TextWriter.Dispose()
   at System.IO.TextWriter.Dispose()
   at System.IO.TextWriter.SyncTextWriter.Dispose(Boolean disposing)
   at System.IO.TextWriter.Dispose()
   at NUnit.Common.ExtendedTextWrapper.Dispose(Boolean disposing) in C:\src\nunit\nunit\src\NUnitFramework\nunitlite\ExtendedTextWrapper.cs:line 83
   at System.IO.TextWriter.Dispose()
   at NUnitLite.TextRunner.Execute(String[] args) in C:\src\nunit\nunit\src\NUnitFramework\nunitlite\TextRunner.cs:line 149
   at NUnitLite.AutoRun.Execute(String[] args) in C:\src\nunit\nunit\src\NUnitFramework\nunitlite\AutoRun.cs:line 82
   at UserQuery.Main()

2 个答案:

答案 0 :(得分:1)

问题是运行程序试图处理linqpad正在使用的输出和错误流。最终,由于它目前正在使用中并且打算保持打开状态,因此会导致错误。

如果将输出和错误流重定向到控制台本身上的文件或运行器的参数(--out--err参数),则可以避免此问题。

但是,在linqpad中运行它的全部目的是使结果显示在结果窗格中。因此,您可以做的是在流周围创建一个包装,而忽略处理调用。

void Main()
{
    var workDir = Path.Combine(Util.MyQueriesFolder, "nunit-work");
    var args = new string[]
    {
        "-noh",
        $"--work={workDir}",
    };
    RunUnitTests(args);
}

void RunUnitTests(string[] args, Assembly assembly = null)
{
    Console.SetOut(new NoDisposeTextWriter(Console.Out));
    Console.SetError(new NoDisposeTextWriter(Console.Error));
    new AutoRun(assembly ?? Assembly.GetExecutingAssembly()).Execute(args);
}

class NoDisposeTextWriter : TextWriter
{
    private readonly TextWriter writer;
    public NoDisposeTextWriter(TextWriter writer) => this.writer = writer;

    public override Encoding Encoding => writer.Encoding;
    public override IFormatProvider FormatProvider => writer.FormatProvider;
    public override void Write(char value) => writer.Write(value);
    public override void Flush() => writer.Flush();
    // forward all other overrides as necessary

    protected override void Dispose(bool disposing)
    {
        // no nothing
    }
}

答案 1 :(得分:1)

每个Jeff的上述回答都将NoDisposeTextWriter作为MyExtensions中的公共类,因此它始终可用。

然后您的主要内容如下所示:

file(s) not in client view