MATLAB: How to create a unit testing mocking framework for function files

MATLAB

We have 'first.m' file with function "first" inside and 'second.m' file with function "second" inside. Both are basic scripts with no OOD. From function "first" we call function "second". I want to fake behavior of function "second" without having to change the file first.m. This is to be done for the unit testing of 'first.m'.

Best Answer

Mocking framework is typical in a lot of testing frameworks. Unfortunately, the methods mentioned in the link below are designed to work on objects and not functions.
To mock function files, there are two ways that I can think of:
1. To create a mock function for 'second', an easy way would be to create a sub folder in the parent folder having 'first' and 'second', and add the newly created subfolder to the MATLAB path using 'addpath', right before the function call to 'second' from 'first'.
This subfolder can have a dummy 'second' function which returns only stub or mock values which would enable 'first' to continue execution.
2. The second way is to use 'PathFixture', while writing the tests, which is a fixture for adding a folder to the MATLAB path.
This will be easier to explain with an example. Please find attached 4 files, 'first.m', an actual 'second.m', the dummy 'second.m' and the unit test file 'tFirst.m', which tests 'first.m', with dummy 'second.m'
If 'home' is my current working directory, then the location of the files are as
\home\tFirst.m
\home\src\first.m
\home\src\second.m (This is the actual 'second.m')
\home\mocks\second.m (This is the dummy 'second.m')
Considering '\home' as the Current directory, the folder '\home\src' has to be added to the path first.
As can be seen in the file 'tFirst.m', adding the two lines of code
import matlab.unittest.fixtures.PathFixture;
testCase.applyFixture(PathFixture(fullfile(pwd,'mocks')));
sets up the fixture such that when 'second' is called from 'first' during the unit test, the dummy 'second' in '\home\mocks' is called.
The dummy 'second.m' must be set up to return stub values and avoid execution of the actual 'second.m'.