dsian.TwinCAT.Ads.Server.Mock
0.5.0
See the version list below for details.
dotnet add package dsian.TwinCAT.Ads.Server.Mock --version 0.5.0
NuGet\Install-Package dsian.TwinCAT.Ads.Server.Mock -Version 0.5.0
<PackageReference Include="dsian.TwinCAT.Ads.Server.Mock" Version="0.5.0" />
paket add dsian.TwinCAT.Ads.Server.Mock --version 0.5.0
#r "nuget: dsian.TwinCAT.Ads.Server.Mock, 0.5.0"
// Install dsian.TwinCAT.Ads.Server.Mock as a Cake Addin
#addin nuget:?package=dsian.TwinCAT.Ads.Server.Mock&version=0.5.0
// Install dsian.TwinCAT.Ads.Server.Mock as a Cake Tool
#tool nuget:?package=dsian.TwinCAT.Ads.Server.Mock&version=0.5.0
dsian.TwinCAT.Ads.Server.Mock
Mocking a TwinCAT Ads Server, for unit testing code with ADS read/write requests.
With this Nuget package it is possible to test your code even if it is relying on TwinCAT.Ads.dll
calls and dependencies on that library (e.g. TwinCAT.Ads.TypeSystem.SymbolFactory
).
You don't need to setup a PLC or TwinCAT runtime to test your code, hence no special requirements on a build server.
How to
Setup mocking server
ushort port = 12345; string portName = "MyTestAdsServer"; using (var mockServer = new Mock(port, portName)) // ILogger optional { // ... }
Register Behaviors
mockServer.RegisterBehavior(new ReadIndicationBehavior(1, 123, Enumerable.Range(1,32).Select(i => (byte)i).ToArray())) .RegisterBehavior(new ReadIndicationBehavior(1, 1, Encoding.UTF8.GetBytes("acting as a ADS server"))) .RegisterBehavior(new ReadIndicationBehavior(0, 0, null, AdsErrorCode.DeviceAccessDenied)) .RegisterBehavior(new WriteIndicationBehavior(0, 0, 22));
- Behaviors
Behaviros likeReadIndicationBehavior
are used as enpdpoint for a specific ADS call, e.g.
Anew ReadIndicationBehavior(1, 123, Enumerable.Range(1,32).Select(i => (byte)i).ToArray())
ReadAsync
ADS call is made toIndexGroup=1
,IndexOffset=123
withLength=32
, in this case the server will return 32 bytes (0x01..0x20) to the client.
- Behaviors
Test
For example, the class we want to test:using System; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Sample { public class MyAdsClass { public MyAdsClass(int port) { Port = port; } public int Port { get; } private byte[] _buffer = new byte[32]; public async Task<byte[]> GetValuesFilteredAsync(uint ig, uint io, Func<byte, bool> filterFunc) { using (var client = new TwinCAT.Ads.AdsClient()) { client.Connect(Port); var result = await client.ReadAsync(ig, io, _buffer, CancellationToken.None); if (result.Succeeded) return _buffer.Where(x => filterFunc(x)).Select(x => x).ToArray(); } return new byte[0]; } } }
Unit test:
[TestMethod] public async Task Should_filter_even_and_odd_values() { // arrange ushort port = 12345; string portName = "MyTestAdsServer"; using (var mockServer = new Mock(port, portName)) // ILogger optional { mockServer.RegisterBehavior(new ReadIndicationBehavior(1, 123, Enumerable.Range(1, 32).Select(i => (byte)i).ToArray())); var myAdsCls = new MyAdsClass(mockServer.ServerAddress.Port); // act var even = await myAdsCls.GetValuesFilteredAsync(1, 123, (x) => x % 2 == 0); var odd = await myAdsCls.GetValuesFilteredAsync(1, 123, (x) => x % 2 != 0); // assert Assert.IsTrue(even.SequenceEqual(new byte[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32 })); Assert.IsTrue(odd.SequenceEqual(new byte[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 })); } }
Example
// setup mocking server
ushort port = 12345;
string portName = "MyTestAdsServer";
using (var mockServer = new Mock(port, portName))
{
var serverBuffer = new byte[65535];
mockServer.RegisterBehavior(new ReadIndicationBehavior(1, 123, Enumerable.Range(1,32).Select(i => (byte)i).ToArray()))
.RegisterBehavior(new ReadIndicationBehavior(1, 1, Encoding.UTF8.GetBytes("acting as a ADS server")))
.RegisterBehavior(new ReadIndicationBehavior(0, 0, null, AdsErrorCode.DeviceAccessDenied))
.RegisterBehavior(new WriteIndicationBehavior(0, 0, 22));
Console.WriteLine("Server up and running");
// now the actual Ads Read/WriteRequests...
// create TwinCAT Ads client
using (var client = new AdsClient(logger))
{
// connect to our mocking server
client.Connect(port);
if (client.IsConnected)
{
var readBuffer = new byte[65535];
var readMemory = new Memory<byte>(readBuffer);
var writeBuffer = new byte[65535];
var writeMemory = new Memory<byte>(writeBuffer);
// 1st behavior
var resRd = await client.ReadAsync(1, 123, readMemory[..32], CancellationToken.None);
// 2nd behavior
resRd = await client.ReadAsync(1, 1, readMemory, CancellationToken.None);
Console.WriteLine(Encoding.UTF8.GetString(readMemory.Slice(0,resRd.ReadBytes).Span));
// 3rd behavior
resRd = await client.ReadAsync(0, 0, readMemory, CancellationToken.None);
// 4th behavior
var resWr = await client.WriteAsync(0, 0, writeMemory[..22], CancellationToken.None);
}
}
}
See SampleConsole
and UnitTestSample
for functional examples.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net5.0
- Beckhoff.TwinCAT.Ads.Server (>= 5.0.297)
- Beckhoff.TwinCAT.Ads.TcpRouter (>= 5.0.297)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on dsian.TwinCAT.Ads.Server.Mock:
Package | Downloads |
---|---|
dsian.TwinCAT.Ads.Server.Mock.Extensions
Some extension methods for dsian.TwinCAT.Ads.Server.Mock |
GitHub repositories
This package is not used by any popular GitHub repositories.