In the following example, we demonstrate how to test a function which depends on System.Counter.
Again we use Dependency Injection to abstract from the concrete implementation of the system function:
INTERFACE PUBLIC ICount
METHOD CounterImpl : LINT
END_METHOD
END_INTERFACE
This is the implementing class:
CLASS PUBLIC CountImpl IMPLEMENTS ICount
VAR PUBLIC
MySystemCounter : System.Counters.Counter;
END_VAR
METHOD PUBLIC CounterImpl : LINT
VAR_TEMP
value : LINT;
END_VAR
MySystemCounter();
END_METHOD
END_CLASS
Let the class under test use the interface ICount, so that the class is independent of the system implementation.
CLASS UsingCounterImpl
VAR PUBLIC
Count : ICount;
END_VAR
METHOD PUBLIC CountedEnough : BOOL
VAR_TEMP
myValue : LINT;
END_VAR
myValue := Count.CounterImpl();
IF myValue > 9 THEN
CountedEnough := TRUE;
ELSE
CountedEnough := FALSE;
END_IF;
END_METHOD
END_CLASS
Writing the mock now enables you to control the output variable of the FB. Here it is set to the value of the input variable:
CLASS PUBLIC CountMock IMPLEMENTS ICount
VAR PUBLIC
MySystemCounter : CounterFB_Mock;
END_VAR
METHOD PUBLIC CounterImpl : LINT
VAR_TEMP
value : LINT;
END_VAR
MySystemCounter();
END_METHOD
END_CLASS
// Here you can control your value
FUNCTION_BLOCK CounterFBMock
VAR_INPUT
valueToSet : LINT;
END_VAR
VAR_OUTPUT
value : LINT;
END_VAR
value := valueToSet;
END_FUNCTION_BLOCK
Finally, you can write your test:
{TestFixture}
CLASS MyTestFixture
VAR
_myVar : UsingCounterImpl;
_myMock : CountMock;
END_VAR
{Test}
METHOD PUBLIC MyTestMethod
_myVar.Count := myMock;
_myMock.MySystemCounter.valueToSet := 10;
Assert.Equal(_myVar.CountedEnough(), TRUE);
END_METHOD
END_CLASS