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 } } } }