NUniteLite 3.11.0 создает исключение пустых ссылок с помощью автозапуска в LINQpad - PullRequest
0 голосов
/ 19 октября 2018

Следующий запрос LINQPad выбрасывает NullReferenceException в блок try-catch:

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 голосов
/ 16 апреля 2019

Согласно приведенному выше ответу Джеффа, NoDisposeTextWriter должен быть общедоступным классом в MyExtensions, чтобы он всегда был доступен.

Тогда ваш основной файл может выглядеть следующим образом:

void Main()
{
    var cwd = Util.MyQueriesFolder;
    var args = new[] {
        "-noheader", 
        $"-work:{cwd}"
    };

    Console.SetOut(new NoDisposeTextWriter(Console.Out));
    Console.SetError(new NoDisposeTextWriter(Console.Error));
    new AutoRun(Assembly.GetExecutingAssembly()).Execute(args);
}

public class Foo{...}

[TextFixture]
public class TestFoo{...}
0 голосов
/ 13 декабря 2018

Проблема в том, что бегун пытается расположить потоки вывода и ошибок, которые использует linqpad.В конечном счете, поскольку он в настоящее время используется и должен оставаться открытым, это приводит к ошибке.

Эту проблему можно избежать, если перенаправить потоки вывода и ошибок в файл либо на самой консоли, либо аргументами длябегун (--out и --err params).

Тем не менее, весь смысл его запуска в linqpad заключается в том, что результаты отображаются на панели результатов.Поэтому вы можете создать оболочку для потоков, которая игнорирует вызовы dispose.

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
    }
}
...