Configurable Mocks - Manual - AxUnit - AxUnit - AxUnit,

AxUnit (legacy) CLI Tool (test)

Portfolio
SIMATIC AX
Product
AxUnit
Software version
2.0.9
Edition
08/2025
Language
English (original)
Package Name
@ax/axunit-docs

Sometimes it is necessary to write stateful mocks, which return different values depending on their state. In the following example the function ActiveWait waits until the waitingTime is elapsed and returns true. Therefore, the first call of GetOperatingTime sets the startTime initially. The elapsed time is reset in a while loop using the startTime and the return value of GetOperatingTime. With each iteration, the return value of GetOperatingTime is incremented.

FUNCTION ActiveWait : BOOL
    VAR_INPUT
        waitingTime: LTIME;
    END_VAR
    VAR_TEMP
        elapsedTime : LTIME;
        startTime : LTIME;
        ticks : INT := 0;
    END_VAR

    startTime := GetOperatingTime();

    WHILE elapsedTime < waitingTime DO
        elapsedTime := GetOperatingTime() - startTime;
        ticks := ticks + 1;
    END_WHILE;
    ActiveWait := TRUE;

END_FUNCTION

To be able to write a unit test for ActiveWait, the function GetOperatingTime must be mocked. For such scenarios AxUnit offers the possibility to implement stateful mocks, which are able to return values depending on their state. Therefore, the function AxUnit.Mocking.Mock<mockee, mock, IPayload> accepts an optional third parameter. The optional parameter must implement the interface IPayload. The payload can be used inside of the mock. The class TestActiveWait uses this technique and passes the state variable to the GetTickMock.

{TestFixture}
CLASS TestActiveWait
    VAR
            state : GetTickMockState;
    END_VAR

    {Test}
    METHOD PUBLIC Should_reached_waiting_time
        AxUnit.Mocking.Mock('Siemens.Simatic.S71500.Clocks.GetOperatingTime', NAME_OF(GetTickMock), THIS._state);
        AxUnit.Assert.Equal(TRUE, ActiveWait(LTIME#5s));
    END_METHOD

END_CLASS

Inside GetTickMock, the GetPayload() function is used to unbox the state. The state is incremented by 10 each time the mock is called. The result is saved in the instance of TestActiveWait. In this example the GetTickMock returns: 0,10,20,30,40,50 and the test TestActiveWait passes.

FUNCTION GetTickMock : LTIME
    VAR_TEMP
        state : REF_TO GetTickMockState;
    END_VAR

    state ?= AxUnit.Mocking.GetPayload();
    state^.value := state^.value + T#10ms;
    GetTickMock := state^.value;
END_FUNCTION

CLASS GetTickMockState IMPLEMENTS AxUnit.Mocking.IPayload
    VAR PUBLIC
        value : LTIME := T#0s;
    END_VAR
END_CLASS

Note

It is crucial for AxUnit that the payload is provided by the mock setup. Otherwise, AxUnit.Mocking.GetPayload() will return null.