2016-06-29 21 views
2

私はコンピュータサイエンスには新しく、ネットワークに関する知識はほとんどありません。 私はインターンシップで仕事を得ました。これはInterfaceを実装してTCPClientをモックすることです。 実際のサーバに接続する必要がないので、データを受信して​​保存して送信するには、疑似TCPClientが必要です。私が理解していることから、TCPClientでsendmessage関数を擬似するだけですか?インターフェイスを実装してTCPClientをモックする方法

public interface ITCPClient 
{ 
    /// <summary> 
    /// Event handler when TCP client is connected 
    /// </summary> 
    event ConnectionEventHandler Connected; 

    /// <summary> 
    /// Event handler for TCP Client on receiving data 
    /// </summary> 
    event DataReceivedEventHandler DataReceived; 

    /// <summary> 
    /// Event handler when TCP client is disconnect 
    /// </summary> 
    event ConnectionEventHandler Disconnected; 

    /// <summary> 
    /// Reports error when an error occurs 
    /// </summary> 
    event ErrorEventHandler OnError; 

    /// <summary> 
    /// Set whether to use HostByteOrder or NetworkByteorder with the socket - gateway expects network byte order 
    /// </summary> 
    bool ByteOrder { get; set; } 

    /// <summary> 
    /// Returns true if the client is running and connected to the server 
    /// </summary> 
    bool IsRunning { get; } 

    /// <summary> 
    /// Add the message to the sendqueue. The message will be processed by the ProcessMessage function waiting for the message. 
    /// </summary> 
    /// <param name="Message"></param> 
    void SendMessage(string Message); 

    /// <summary> 
    /// Add the message to the sendqueue. The message willbe processed by the ProcessMessage function waiting for the message. 
    /// </summary> 
    /// <param name="Message"></param> 
    void SendMessageHiPriority(string Message); 

    /// <summary> 
    /// Starts the client and spawn the thread for processing the message 
    /// </summary> 
    void Start(); 

    /// <summary> 
    /// Disconnects and stops listening for messages 
    /// </summary> 
    void StopProcessing(); 

} 

public class MockTCPClient : ITCPClient 
{ 
    #region Private Fields 

    private string msg; 

    #endregion Private Fields 


    #region Constructor 

    public MockTCPClient() 
    { 
     //nothing 
    } 


    #endregion Constructor 

    #region event 

    public event ConnectionEventHandler Connected; 
    public event ConnectionEventHandler Disconnected; 
    public event ErrorEventHandler OnError; 
    public event DataReceivedEventHandler DataReceived; 

    #endregion event 

    #region property 
    //question 
    public string ReceivedMessage 
    { 
     get 
     { 
      return msg; 
     } 

     set 
     { 
      msg = value; 
     } 

    } 

    #endregion property 

    //question?? 
    private void OnDataReceived(object sender, string e) 
    { 
     DataReceivedEventHandler dataReceived = DataReceived; 
     if (dataReceived != null) 
      dataReceived(this, e); 
    } 


    #region ITCPClient Members 
    #region properties 

    public bool ByteOrder { get; set; } 


    public bool IsRunning { get; } 

    #endregion properties 

    public void SendMessage(string Message) 
    { 
     msg = Message; 
    } 

    public void SendMessageHiPriority(string Message) 
    {  
    } 

    public void Start() 
    { 
    } 


    public void StopProcessing() 
    { 
    } 


    #endregion ITCPClient Members 

} 
+0

インターフェイス全体を実装する代わりに、模擬フレームワークを使用できます。テストに必要な部分だけを設定し、完了します。 Moq、NS代理店で読んで、さらにいくつかあります。また、TcpClientがどのように動作するかを読んで、あなたが模擬する必要があることを知っておくことをお勧めします。 – Nkosi

+0

ITCPClientのどのメソッドとプロパティーで、クラスと対話する必要があるのか​​を明確にすることはできますか? –

+0

@ScottHannenはい。このメソッドはvoid SendMessage(文字列メッセージ)です。また、イベントDataReceivedEventHandler DataReceivedも考慮されると思います。しかし、私はどのようにC#でイベントを実装するのか分かりません。 SendMessageメソッドは、元のTCPClientで処理されるキューにメッセージをエンキューするために使用されます。私は私の質問をはっきりと説明するかどうか分からない。ありがとうございました! – lancwl

答えて

1

これは、あなたのクラスがそのメソッドの1つを呼び出していることをMoqがどのように検証できるかを示しています。

この試験
は - ITCPClient
のモックを作成 - SendMessage方法は検証であることを指定 - 言い換えれば、その使用を追跡します。
- 模擬オブジェクトでSendMessage("test");が呼び出されたことを確認します。私たちは、テストに合格しますSendMessage("test")を呼び出す行のコメントを解除した場合、それはSendMessage("test");

[TestMethod] 
public void TestTcpClient() 
{ 
    var mockedTcpClient = new Mock<ITCPClient>(); 
    mockedTcpClient.Setup(x => x.SendMessage(It.IsAny<string>())).Verifiable(); 
    //mockedTcpClient.Object.SendMessage("test"); 
    mockedTcpClient.Verify(x=>x.SendMessage("test")); 
} 

を呼び出すことはありませんので、

テストは失敗します。

したがって、実際の使用では、Mockを作成し、それに依存するクラスをテストするときはITCPClientの代わりに使用します。完了したら、あなたのクラスがSendMessageと呼ばれ、期待値を超えたVerifyができます。

あなたは、部品番号を使用することができない場合は、ここでは全く異なるアプローチです:

は、次のようにITCPClient実装するクラスを作成します。あなたは方法のほとんど空のままにしてわずか数その他の詳細と共にSendMessageを実装することができます:あなたのユニットテストで

public class TcpClientMock : ITCPClient 
{ 
    private readonly List<string> _sentMessages; 

    public TcpClientMock(List<string> sentMessages) 
    { 
     _sentMessages = sentMessages; 
    } 

    public void SendMessage(string Message) 
    { 
     _sentMessages.Add(Message); 
    } 

    //rest of non-implemented methods 
} 

、次の操作を行います。

var sentMessages = new List<string>(); 
var mockedTcpClient = new TcpClientMock(sentMessages); 

を次にあなたがしようとしているものは何でもクラスの作成それを試して行動してください。完了したら、sentMessagesに期待するメッセージが含まれているかどうかを確認してください。データを受信する場合


、私はあなたが期待通りにイベントが発生したときに、あなたのクラスが応答していることを確認できたので、そのイベントを発生させるためにあなたの嘲笑のオブジェクトに伝える必要があると思いますと仮定します。あなたはこのようなTcpClientMockにメソッドを追加することができます。

public void SimulateDataReceived(object sender, DataReceivedEventHandlerArgs args) 
{ 
    DataReceived(sender, args); 
} 

その方法をあなたはITCPClientに依存して、あなたのクラスを設定したとき、あなたはそれがイベントを発生させる原因となる、モックにSimulateDataReceivedを呼び出すことができ、順番になります被験者に反応させる。

+0

それは非常に明確に見え、私は基本的な考えを持っていると思う!お返事ありがとうございました!もう1つの質問。単体テストについては、SimulateDataReceivedメソッドもテストする必要がありますか? – lancwl

+0

別の質問がある場合は、コメントを使用する代わりに別の質問を開始してください。これが正しければ、答えとしてマークする必要があります。これは、同様の問題を抱えている可能性のある他のユーザーに役立ちます。また、評判に答えたユーザーにも賞を与えます。あなたの質問はうまく書かれているので、アップヴォートを得ました:) –

+0

'SimulateDataReceived'をテストする必要はありません。このメソッドは、 'DataReceived'イベントの発生をシミュレートするために使用できます。しかし、それがあなたがシミュレートする必要があるものでないなら、あなたはそれを完全に無視することができます。 –

関連する問題