代码之家  ›  专栏  ›  技术社区  ›  sapbucket

Resharper测试运行程序未输出控制台。WriteLine()?

  •  5
  • sapbucket  · 技术社区  · 7 年前

    为什么会这样 Console.Writeline() 从控制台应用程序执行时将工作 main() 方法但是,当我使用resharpers测试运行程序执行相同的测试时,我没有看到 安慰Writeline() 在test runner输出窗口中?

    最好的解释方法是用一个例子。

    我正在使用:Resharper Ultimate 2017.1.3、Visual Studio 2017社区和。Net 4.6.1框架。语言是C。我还(通过nuget)安装了nunit framework 2.6.4。

    首先创建一个类库,并将以下内容复制粘贴到中。cs文件。

    using System;
    using System.Collections;
    using System.Threading;
    using NUnit.Framework;
    
    namespace ObserverPatternExample
    {
        [TestFixture]
        internal class ObserverTestFixture
        {
            [Test]
            public void DemonstrateObserverPattern()
            {
                var subject = new Subject();
                var a = new Observer(subject, "a");
                var b = new Observer(subject, "b"); // etc. as many observers as you want.
    
                subject.Go();
            }
        }
    
        // "subject" is observer pattern lingo. The "subject" will do the broadcasting to the observers.
        public class Subject 
        {
            public delegate void CallbackHandler(string s);
            public event CallbackHandler NotifyEvent;
            private const int waitTimeInMilliseconds = 200;
            private readonly Simulator simulator = new Simulator();
            public string FakeSimulatorState { get; set; }
    
            public void Go()
            {
                new Thread(Run).Start(); // a good thing to notice: events cross thread boundaries!!!
            }
    
            private void Run()
            {
                foreach (string s in simulator)
                {
                    Console.WriteLine("Subject: " + s);
                    FakeSimulatorState = s;
                    NotifyEvent?.Invoke(s);
                    Thread.Sleep(
                        waitTimeInMilliseconds); // we do this to "pretend" that the simulator is actually doing someting.
                }
            }
    
    
        }
    
        public class Observer : IObserverPattern // the "observer" will subscribe to the event being broadcast by the "subject"
        {
            private readonly string _name;
            public Observer(Subject subject, string name)
            {
                _name = name;
                subject.NotifyEvent += Update;
            }
            public void Update(string state)
            {
                Console.WriteLine("Observer {0}: {1}", _name, state);
            }
        }
    
        internal interface IObserverPattern
        {
            void Update(string state);
        }
    
        public class Simulator : IEnumerable
        {
            private readonly string[] _stateSequence = { "BEGIN", "CRAWL", "WALK", "JUMP", "END" };
    
            public IEnumerator GetEnumerator()
            {
                foreach (var s in _stateSequence)
                    yield return s;
            }
        }
    }
    

    现在执行测试。我希望看到控制台。WriteLine()调用Resharper测试运行器输出窗口中的显示字符串。但我没有。例如,这里有一个屏幕截图:

    enter image description here

    现在让我们执行完全相同的序列,但这次我们将从一个新的控制台项目main()方法调用客户机代码。要设置此副本,请粘贴以下代码并引用在上述步骤中创建的类库。

    using ObserverPatternExample;
    
    namespace ConsoleApp1
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                var subject = new Subject();
                var a = new Observer(subject, "a");
                var b = new Observer(subject, "b"); // etc. as many observers as you want.
    
                subject.Go();
            }
        }
    }
    

    enter image description here

    谁能解释一下我如何配置我的代码或测试运行程序以在测试运行程序输出窗口中显示输出?

    *更新* 我取得了部分成功。中间人建议使用 TraceListener 让我意识到我应该使用 ConsoleTraceListener . 为了实现这一点,我修改了单元测试,使其看起来像这样:

    using System.Threading;
    using NUnit.Framework;
    
    namespace ObserverPatternExample.DontUse
    {
        [TestFixture]
        internal class ObserverTestFixture
        {
            [SetUp]
            public void Setup()
            {
                Trace.Listeners.Add(new ConsoleTraceListener());
            }
    
            [TearDown]
            public void TearDown()
            {
                Trace.Flush();
            }
    
            [Test]
            public void DemonstrateObserverPattern()
            {
                var subject = new Subject();
                var a = new Observer(subject, "a");
                var b = new Observer(subject, "b"); // etc. as many observers as you want.
    
                subject.Go();
            }
        }
    

    enter image description here

    短篇故事:我仍在寻找解决方案。

    ***解决方案****

            [Test]
            public void DemonstrateObserverPattern()
            {
                var subject = new Subject();
                var a = new Observer(subject, "a");
                var b = new Observer(subject, "b"); // etc. as many observers as you want.
    
                subject.Go();
    
    Thread.Sleep(1000); // <--- add this to force test runner to wait for other thread to complete.
            }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Stephen Straton    7 年前

    看起来Resharper在线程完成之前就完成了。您的呼叫

    Thread(Run).Start();
    

    是非阻塞的。这意味着测试线程将在Go线程之前完成,因此不会得到任何结果。

    看见 https://msdn.microsoft.com/en-us/library/6x4c42hc(v=vs.110).aspx where is states“请注意,对Start的调用不会阻止调用线程。”