176 lines
5.1 KiB
C#
176 lines
5.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net.Sockets;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Moq;
|
|
|
|
namespace AMWD.Common.Test
|
|
{
|
|
/// <summary>
|
|
/// Wrapps the <see cref="Mock{TcpClient}"/> including the setup.
|
|
/// </summary>
|
|
public class TcpClientMoq
|
|
{
|
|
private readonly Mock<NetworkStream> streamMock;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="TcpClientMoq"/> class.
|
|
/// </summary>
|
|
public TcpClientMoq()
|
|
{
|
|
Callbacks = new();
|
|
Response = new byte[0];
|
|
|
|
streamMock = new();
|
|
streamMock
|
|
.Setup(s => s.WriteAsync(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
|
|
.Callback<byte[], int, int, CancellationToken>((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<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
|
|
.Callback<byte[], int, int>((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<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
|
|
.Callback<byte[], int, int, CancellationToken>((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<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
|
|
.Callback<byte[], int, int>((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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the mocked <see cref="TcpClient"/>.
|
|
/// </summary>
|
|
public Mock<TcpClient> Mock { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the placed request.
|
|
/// </summary>
|
|
public List<TcpClientCallback> Callbacks { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the byte response, that should be "sent".
|
|
/// </summary>
|
|
public byte[] Response { get; set; }
|
|
|
|
/// <summary>
|
|
/// Resets the <see cref="Response"/> and <see cref="Callbacks"/>.
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
Response = new byte[0];
|
|
Callbacks.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies the number of calls writing asynchronous to the stream.
|
|
/// </summary>
|
|
/// <param name="times">Number of calls.</param>
|
|
public void VerifyWriteAsync(Times times)
|
|
=> streamMock.Verify(s => s.WriteAsync(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()), times);
|
|
|
|
/// <summary>
|
|
/// Verifies the number of calls writing synchronous to the stream.
|
|
/// </summary>
|
|
/// <param name="times">Number of calls.</param>
|
|
public void VerifyWriteSync(Times times)
|
|
=> streamMock.Verify(s => s.Write(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()), times);
|
|
|
|
/// <summary>
|
|
/// Verifies the number of calls reading asynchronous from the stream.
|
|
/// </summary>
|
|
/// <param name="times">Number of calls.</param>
|
|
public void VerifyReadAsync(Times times)
|
|
=> streamMock.Verify(s => s.ReadAsync(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()), times);
|
|
|
|
/// <summary>
|
|
/// Verifies the number of calls reading synchronous from the stream.
|
|
/// </summary>
|
|
/// <param name="times">Number of calls.</param>
|
|
public void VerifyReadSync(Times times)
|
|
=> streamMock.Verify(s => s.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()), times);
|
|
|
|
/// <summary>
|
|
/// Represents the placed TCP request.
|
|
/// </summary>
|
|
public class TcpClientCallback
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the type (a/synchronous call).
|
|
/// </summary>
|
|
public WriteType Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the buffer content.
|
|
/// </summary>
|
|
public byte[] Buffer { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the offset.
|
|
/// </summary>
|
|
public int Offset { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the byte count.
|
|
/// </summary>
|
|
public int Count { get; set; }
|
|
|
|
/// <summary>
|
|
/// Lists the possible request types.
|
|
/// </summary>
|
|
public enum WriteType
|
|
{
|
|
/// <summary>
|
|
/// The request was synchronous.
|
|
/// </summary>
|
|
Synchronous = 1,
|
|
|
|
/// <summary>
|
|
/// The request was asynchronous.
|
|
/// </summary>
|
|
Asynchronous = 2
|
|
}
|
|
}
|
|
}
|
|
}
|