classdef FunctionHandleTestCase < TestCase %FunctionHandleTestCase Test case based on a function handle % FunctionHandleTestCase is a TestCase subclass. It defines a test case object % that executes by running a function handle instead of by running a method of % the TestCase subclass. % % FunctionHandleTestCase methods: % FunctionHandleTestCase - Constructor % runTestCase - Run function handle test % setUp - Run test-fixture setup function % tearDown - Run test-fixture teardown function % % FunctionHandleTestCase properties: % TestFcn - Function handle of test function % SetupFcn - Function handle of setup function % TeardownFcn - Function handle of teardown function % TestData - Data needed by test function or teardown function % % See also TestCase, TestSuite % Steven L. Eddins % Copyright 2008-2009 The MathWorks, Inc. properties (SetAccess = protected, GetAccess = protected, Hidden = true) %TestFcn - Function handle of test function % If SetupFcn has one or more output arguments, then TestFcn is % called with this syntax: % % TestFcn(data) % % where data is the return value from SetupFcn. Otherwise, TestFcn is % called with no input and no output arguments. TestFcn; %SetupFcn - Function handle of setup function % If SetupFcn has one or more output arguments, then SetupFcn is % called with this syntax: % % data = SetupFcn() % % and data will be saved in the TestData property. Otherwise, SetupFcn % is called with no input and no output arguments. SetupFcn; %TeardownFcn - Function handle of teardown function % If SetupFcn has one or more output arguments, then TeardownFcn is % called with this syntax: % % TeardownFcn(data) % % were data is the return value from SetupFcn. Otherwise, TeardownFcn % is called with no input and no output arguments. TeardownFcn; %TestData - Data needed by test function or teardown function. TestData; end methods function self = FunctionHandleTestCase(testFcn, setupFcn, teardownFcn) %FunctionHandleTestCase Constructor % FunctionHandleTestCase(testFcn, setupFcn, teardownFcn) creates a % TestCase object that executes by running the function handle % TestFcn. setupFcn is a function handle that will be executed % before testFcn, and teardownFcn is a function handle that will % be executed after TestFcn. Either setupFcn or teardownFcn can % be empty. % % If setupFcn is function handle that has one output argument, % then the three test functions will be called using these % syntaxes: % % testData = setupFcn(); % testFcn(testData); % teardownFcn(testData); % % Otherwise, the three test functions are all called with no input % arguments: % % setupFcn(); % TestFcn(); % teardownFcn(); % Call the base class constructor. Give it the name of the % FunctionHandleTestCase method that executes TestFcn. self = self@TestCase('runTestCase'); self.TestFcn = testFcn; self.SetupFcn = setupFcn; self.TeardownFcn = teardownFcn; % Determine the name and M-file location of the function handle. functionHandleInfo = functions(testFcn); self.Name = functionHandleInfo.function; if strcmp(functionHandleInfo.type, 'anonymous') % Anonymous function handles don't have an M-file location. self.Location = ''; else self.Location = functionHandleInfo.file; end end function runTestCase(self) %runTestCase Run function handle test % test_case.run() calls the test function handle. If a nonempty % SetupFcn was provided and it has at least one output argument, % pass self.TestData to the test function. Otherwise, call the % test function with no input arguments. if ~isempty(self.SetupFcn) && nargout(self.SetupFcn) > 0 self.TestFcn(self.TestData); else self.TestFcn(); end end function setUp(self) %setUp Run test-fixture setup function % If a nonempty SetupFcn was provided, run it. If the SetupFcn % has at least one output argument, capture the first output % argument in instance data (TestData). if ~isempty(self.SetupFcn) if nargout(self.SetupFcn) > 0 if nargout(self.SetupFcn) > 1 message = sprintf(['A test fixture setup function returns more than one output argument. ', ... 'The test harness only calls the setup function with one output argument. ', ... 'Return a struct or a cell array from your setup function if you need to bundle several parts together.', ... '\nTest name: %s\nTest location: %s'], ... self.Name, self.Location); warning('xunit:FunctionHandleTestCase:TooManySetupOutputs', ... '%s', message); end self.TestData = self.SetupFcn(); else self.SetupFcn(); end end end function tearDown(self) %tearDown Run test-fixture teardown function % If a nonempty TeardownFcn was provided, run it. If there is % TestData (the output of the SetupFcn), then pass it to % TeardownFcn. Otherwise, call TeardownFcn with no input % arguments. if ~isempty(self.TeardownFcn) if ~isempty(self.SetupFcn) && (nargout(self.SetupFcn) > 0) self.TeardownFcn(self.TestData); else self.TeardownFcn(); end end end end end