using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Moq;
namespace AMWD.Common.Test
{
///
/// Wrapps the including the setup.
///
public class TcpClientMoq
{
private readonly Mock _streamMock;
///
/// Initializes a new instance of the class.
///
public TcpClientMoq()
{
Callbacks = new();
Response = new byte[0];
_streamMock = new();
_streamMock
.Setup(s => s.WriteAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Callback((buffer, offset, count, _) =>
{
var callback = new TcpClientCallback
{
Buffer = new byte[count],
Offset = offset,
Count = count,
Type = TcpClientCallback.WriteType.Asynchronous
};
Array.Copy(buffer, offset, callback.Buffer, 0, count);
Callbacks.Add(callback);
})
.Returns(Task.CompletedTask);
_streamMock
.Setup(s => s.Write(It.IsAny(), It.IsAny(), It.IsAny()))
.Callback((buffer, offset, count) =>
{
var callback = new TcpClientCallback
{
Buffer = new byte[count],
Offset = offset,
Count = count,
Type = TcpClientCallback.WriteType.Synchronous
};
Array.Copy(buffer, offset, callback.Buffer, 0, count);
Callbacks.Add(callback);
});
_streamMock
.Setup(s => s.ReadAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Callback((buffer, offset, count, _) =>
{
byte[] bytes = Response ?? new byte[0];
Array.Copy(bytes, 0, buffer, offset, Math.Min(bytes.Length, count));
})
.ReturnsAsync(Response?.Length ?? 0);
_streamMock
.Setup(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny()))
.Callback((buffer, offset, count) =>
{
byte[] bytes = Response ?? new byte[0];
Array.Copy(bytes, 0, buffer, offset, Math.Min(bytes.Length, count));
})
.Returns(Response?.Length ?? 0);
Mock = new();
Mock
.Setup(c => c.GetStream())
.Returns(_streamMock.Object);
}
///
/// Gets the mocked .
///
public Mock Mock { get; }
///
/// Gets the placed request.
///
public List Callbacks { get; }
///
/// Gets the byte response, that should be "sent".
///
public byte[] Response { get; set; }
///
/// Resets the and .
///
public void Reset()
{
Response = new byte[0];
Callbacks.Clear();
}
///
/// Verifies the number of calls writing asynchronous to the stream.
///
/// Number of calls.
public void VerifyWriteAsync(Times times)
=> _streamMock.Verify(s => s.WriteAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), times);
///
/// Verifies the number of calls writing synchronous to the stream.
///
/// Number of calls.
public void VerifyWriteSync(Times times)
=> _streamMock.Verify(s => s.Write(It.IsAny(), It.IsAny(), It.IsAny()), times);
///
/// Verifies the number of calls reading asynchronous from the stream.
///
/// Number of calls.
public void VerifyReadAsync(Times times)
=> _streamMock.Verify(s => s.ReadAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), times);
///
/// Verifies the number of calls reading synchronous from the stream.
///
/// Number of calls.
public void VerifyReadSync(Times times)
=> _streamMock.Verify(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny()), times);
///
/// Represents the placed TCP request.
///
public class TcpClientCallback
{
///
/// Gets or sets the type (a/synchronous call).
///
public WriteType Type { get; set; }
///
/// Gets or sets the buffer content.
///
public byte[] Buffer { get; set; }
///
/// Gets or sets the offset.
///
public int Offset { get; set; }
///
/// Gets or sets the byte count.
///
public int Count { get; set; }
///
/// Lists the possible request types.
///
public enum WriteType
{
///
/// The request was synchronous.
///
Synchronous = 1,
///
/// The request was asynchronous.
///
Asynchronous = 2
}
}
}
}