コンソールアプリケーションから実行するとConsole.Writeline()
が動作するのはなぜですかmain()
メソッドです。私がresharpersテストランナーを使って同じものを実行すると、テストランナー出力ウィンドウにConsole.Writeline()
が表示されませんか?ResharperテストランナーはConsole.WriteLine()を出力していませんか?
これを説明する最善の方法は例です。
Resharper Ultimate 2017.1.3、Visual Studio 2017 Community、.Net 4.6.1フレームワークを使用しています。言語はC#です。私も(nuget経由で)nunitフレームワーク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();
}
}
}
次に、コンソールアプリケーションを実行します。あなたは、次の表示されるはずです。
を誰もがテストランナーの出力ウィンドウに出力を表示するために、私は設定することができますどのように私のコードやテストランナーのどちらかを説明していただけますか?
* UPDATE * 部分的に成功しました。 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();
}
}
、その結果は驚くべきものである:これをfaciliateするために、私はこのように表示されるようにユニットテストを修正私はいくつかの出力を得るのです。初期のBEGIN状態のみになります。これは次のように表示されます
ショートストーリー:私はまだ解決策を探しています。
*** SOLUTION ****
[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.
}
ユーザーインターフェイスに情報を出力しないと、単体テストの目的が無効になりますか?テストが成功するか失敗するか、コンソールに出力されたものはどのようにその決定に影響を与えますか? – InBetween
デバッグのために 'System.Diagnostics.Debug'と' TraceListener'を使用する必要があります。 – InBetween
@InBetween:ユニットテストアサートメソッドを書く仕事をする同僚のためのこの例を設定します。有用なconsole.writeline()を出力ウィンドウに書くことに何も問題はありません。それは私の同僚が "一目で"状態を見るのを助ける。 – sapbucket