Вы использовали классы нового стиля? Вы можете превратить эту функцию в статический метод в служебном классе. Затем вы можете либо превратить подфункции в другие статические методы, либо превратить подфункции в локальные функции класса и дать классу статический метод, который возвращает им дескрипторы.
classdef fooUtil
methods (Static)
function [things] = myfunc(data)
[stuff] = mysubfunc(data);
things = mean(stuff);
end
function out = getLocalFunctionHandlesForTesting()
onlyAllowThisInsideUnitTest();
out.mysubfunc = @mysubfunc;
out.sub2 = @sub2;
end
end
end
% Functions local to the class
function out = mysubfunc(x)
out = x .* 2; % example dummy logic
end
function sub2()
% ...
end
function onlyAllowThisInsideUnitTest()
%ONLYALLOWTHISINSIDEUNITTEST Make sure prod code does not depend on this encapsulation-breaking feature
isUnitTestRunning = true; % This should actually be some call to xUnit to find out if a test is active
assert(isUnitTestRunning, 'private function handles can only be grabbed for unit testing');
end
Если вы используете синтаксис стиля classdef, все эти функции и любые другие методы могут быть помещены в один файл fooUtil.m; нет беспорядка файловой системы. Или вместо того, чтобы разоблачать личные вещи, вы можете написать тестовый код внутри класса.
Я думаю, что пуристы модульного тестирования скажут, что вам вообще не следует этого делать, потому что вы должны тестировать на общедоступном интерфейсе объекта, и если вам нужно протестировать части, они должны быть разложены на что-то другое. который представляет их в общедоступном интерфейсе. Это говорит в пользу того, чтобы сделать их общедоступными статическими методами и тестировать их напрямую, забывая о предоставлении закрытых функций с помощью дескрипторов функций.
classdef fooUtil
methods (Static)
function [things] = myfunc(data)
[stuff] = fooUtil.mysubfunc(data);
things = mean(stuff);
end
function out = mysubfunc(x)
out = x .* 2; % example dummy logic
end
function sub2()
% ...
end
end
end