Since many of the system functions are implemented as function blocks, we want to show an explicit example how to mock them.
In the example below, there is a productive code function block DependsOnTimer which is using internally system function block OnDelay.
In order to achieve 100% code coverage of this function block, the test code needs to control the result of OnDelay call (see ton() in code),
which potentially changes the value of OnDelay.Output field.
For this purpose, the test code defines a function block OnDelayMock_true and OnDelayMock_false changing Output field to true and false respectively.
The test method DependsOnTimer_returns_true setups the mock for OnDelay so that OnDelayMock_true is called.
And the test method DependsOnTimer_returns_false setups the mock for OnDelay so that OnDelayMock_false is called.
USING System.Timer;
FUNCTION_BLOCK DependsOnTimer
VAR
ton : OnDelay;
END_VAR
VAR_OUTPUT
delayFired : BOOL;
END_VAR
ton();
IF (ton.output) THEN
delayFired:= true;
ELSE
delayFired:=false;
END_IF;
END_FUNCTION_BLOCK
FUNCTION_BLOCK OnDelayMock_true
VAR
iecTimer : ARRAY[0..27] of BYTE;
END_VAR
VAR_INPUT
duration : LTIME;
signal : BOOL;
END_VAR
VAR_OUTPUT
elapsedTime : LTIME;
output : BOOL;
END_VAR
output := TRUE;
END_FUNCTION_BLOCK
FUNCTION_BLOCK OnDelayMock_false
VAR
iecTimer : ARRAY[0..27] of BYTE;
END_VAR
VAR_INPUT
duration : LTIME;
signal : BOOL;
END_VAR
VAR_OUTPUT
elapsedTime : LTIME;
output : BOOL;
END_VAR
output := FALSE;
END_FUNCTION_BLOCK
{TestFixture}
CLASS TestsOnDelay
VAR
testee: DependsOnTimer;
END_VAR
{Test}
METHOD PUBLIC DependsOnTimer_returns_true
VAR_TEMP
result:BOOL;
END_VAR
AxUnit.Mocking.Mock(name_of(System.Timer.OnDelay), name_of(OnDelayMock_true));
testee(result);
AxUnit.Assert.Equal(true, result);
END_METHOD
{Test}
METHOD PUBLIC DependsOnTimer_returns_false
VAR_TEMP
result:BOOL;
END_VAR
AxUnit.Mocking.Mock(name_of(System.Timer.OnDelay), name_of(OnDelayMock_false));
testee(result);
AxUnit.Assert.Equal(false, result);
END_METHOD
END_CLASS