为什么在从控制台应用程序的main()方法执行时,
最好的方法是通过一个例子来解释。
我正在使用:Resharper Ultimate 2017.1.3、Visual Studio 2017 Community和.Net 4.6.1框架。语言是C#。我还安装了(通过nuget)nunit framework 2.6.4。
首先创建一个类库,并将以下内容复制粘贴到.cs文件中。
现在执行测试。我希望在Resharper测试运行器输出窗口中看到Console.WriteLine()调用显示字符串。但是没有。例如,这里是一个截图: 现在让我们执行完全相同的序列,但这次我们将从新控制台项目的main()方法调用客户端代码。为了设置这个,请复制粘贴以下代码并引用您在上面步骤中创建的类库。
接下来执行控制台应用程序。您应该看到以下内容显示: 请问有人能解释一下我如何配置我的代码或测试运行器以在测试运行器输出窗口中显示输出吗?
*更新* 我取得了部分成功。InBetween建议使用TraceListener使我意识到应该使用ConsoleTraceListener。为了实现这个目的,我修改了单元测试,使其看起来像这样:
结果令人惊讶:我确实得到了一些输出;但只有初始的BEGIN状态。它看起来像这样: 翻译:短故事:我仍在寻找解决方案。
Console.Writeline()
可以正常工作;但是当我使用resharpers测试运行器执行相同的操作时,我看不到Console.Writeline()
在测试运行器输出窗口中的输出?最好的方法是通过一个例子来解释。
我正在使用:Resharper Ultimate 2017.1.3、Visual Studio 2017 Community和.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;
}
}
}
现在执行测试。我希望在Resharper测试运行器输出窗口中看到Console.WriteLine()调用显示字符串。但是没有。例如,这里是一个截图: 现在让我们执行完全相同的序列,但这次我们将从新控制台项目的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();
}
}
}
接下来执行控制台应用程序。您应该看到以下内容显示: 请问有人能解释一下我如何配置我的代码或测试运行器以在测试运行器输出窗口中显示输出吗?
*更新* 我取得了部分成功。InBetween建议使用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();
}
}
结果令人惊讶:我确实得到了一些输出;但只有初始的BEGIN状态。它看起来像这样: 翻译:短故事:我仍在寻找解决方案。
***解决方案***
[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.
}
System.Diagnostics.Debug
和你选择的TraceListener
。 - InBetween