Suppose that I have some function Foo
that uses two internal helper functions bar
and baz
.
Is there a way to organize the code
Not the most elegant way to do it but then Matlab is not the most practical language to build modules in a single code file. One way to do it is to have a higher level level function which transfer the input arguments to the function you choose:
function out = fooModule( FunctionCalled , varargin)
%// This main function only transfer the input argument to the function chosen
switch FunctionCalled
case 'main'
out = foo(varargin) ;
case 'bar'
out = mBar(varargin) ;
case 'baz'
out = mBaz(varargin) ;
end
end
function outFoo = foo(varargin)
%// your main FOO code
%// which can call the helper function if necessary
end
function outbar = mBar(varargin)
%// your code
end
function outbaz = mBaz(varargin)
%// your code
end
You can even embed the FunctionCalled
parameter into varargin
if you want to compact things. This would also allow to test the type of the first argument. So for example if the first argument is not a string
(calling one of the helper function) then forward the execution directly to the main foo function without having to call it explicitly (so the helper functions remain 'out of sight' if not called explicitly).
Otherwise, a completely different approach, you could consider writing a class.
There are a few options to achieve this.
First, does Foo
need to be a function? If it is a class then you can implement bar
and baz
as Hidden
and Access='protected'
which is pretty tightly locked down. Then you can create a test specific subclass that accesses bar
and baz
for testing. You can also scope the access to the test to further lock it from others view if desired.
If you do want Foo
to be a function then you still have options. One of those is to somehow get a function handle to the private local functions to your tests. You can do this through some special calling syntax of Foo that returns these functions to a test when called. This however, modifies the production code in a potentially confusing way, and it essentially inserts test logic into production. I would prefer hiding these functions by putting them into a package so that they are not in the global namespace. The name of the package can indicate that they are off limits and not part of your supported interface.
Finally, one option is to simply use the public interface in order to test these functions. Clearly they are called from the function in some scenario. You may want to consider writing a test through the front door of your interface. One benefit of this is that you would then be able to change the implementation of your local function structure easily without modifying your test. The private functions are private because by definition they are part of your implementation, not your interface. If you find it complex enough to require its own test independent from the interface of Foo
then it should probably just be broken out into another package function or class as described above in order to unit test it.