How to save a property inside unittest for various methods?

20 views (last 30 days)
I would like to test instance initiation of a (handle-)class "Someclass" in a test method and save this instance to reuse it in later tests.
My code looks like this:
classdef testSomeclass < matlab.unittest.TestCase
properties
p01
end
methods (Test)
function testInitSomeclass(testCase)
load('./testdata/input.mat');
id = cell2mat(input.ID(3));
year = input.Data(3,22);
fueltype = input.Data(3,23);
testCase.p01 = Someclass(id,'ccs', year, fueltype);
testCase.assertClass(testCase.p01,'Someclass');
end
function testSingleAddSamples(testCase)
load('./testdata/result.mat');
testCase.assertClass(testCase.p02,'Someclass'); % line added for testing
testCase.p01.addSamplesArray('power',result(6,1:60)',(1:60)');
testCase.assertNumElements(testCase.p01.powerTimeline.Data,60);
end
end
end
The testInitSomeclass-method passes when running:
clear;test1 = testSomeclass;run(test1)
but testSingleAddSamples fails:
assertClass failed.
--> The value's class is incorrect.
Actual Class:
double
Expected Class:
Someclass
As p01 is a class property it still should be an instance of 'Someclass'. Maybe you've an idea how to save it with "test method persistence"?

Answers (1)

Andy Campbell
Andy Campbell on 3 Dec 2013
Edited: Andy Campbell on 3 Dec 2013
Hi Nicolas,
It is by design that each test method is its own independent instance. This is done to help ensure order independence of the tests, allowing each test to be run independently. Each test can even be run in parallel. Actually, the order of when the tests are run is not guaranteed and should not be relied upon. A little bit of background on this principle can be found here.
You seem to have a couple options.
1) Create a fresh fixture in each test. This means that you simply need to create a fresh new instance of the object for every test method. In your case, that might look like this, which is an example of delegated setup:
classdef testSomeclass < matlab.unittest.TestCase
methods (Test)
function testInitSomeclass(testCase)
instance = createInstanceFromTestData;
testCase.verifyClass(instance,'Someclass');
end
function testSingleAddSamples(testCase)
instance = createInstanceFromTestData;
s = load(fullfile(pwd,'testdata','result.mat'));
instance.addSamplesArray('power',s.result(6,1:60)',(1:60)');
testCase.assertNumElements(instance.powerTimeline.Data,60);
end
end
end
function instance = createInstanceFromTestData
% local helper function to load the data and create the instance
s = load(fullfile(pwd,'testdata','input.mat'));
id = cell2mat(s.input.ID(3));
year = s.input.Data(3,22);
fueltype = s.input.Data(3,23);
instance = Someclass(id,'ccs', year, fueltype);
end
2) If every test method in this class is going to need the same value, you can use the TestMethodSetup attribute to create this instance for you before every test method. This is an example of implicit setup and could look like:
classdef testSomeclass < matlab.unittest.TestCase
properties
Instance;
end
methods(TestMethodSetup)
function instance = createInstanceFromTestData(testCase)
s = load(fullfile(pwd,'testdata','input.mat'));
id = cell2mat(s.input.ID(3));
year = s.input.Data(3,22);
fueltype = s.input.Data(3,23);
testCase.Instance = Someclass(id,'ccs', year, fueltype);
end
end
methods (Test)
function testInitSomeclass(testCase)
testCase.verifyClass(testCase.Instance,'Someclass');
end
function testSingleAddSamples(testCase)
s = load(fullfile(pwd,'testdata','result.mat'));
testCase.Instance.addSamplesArray('power',s.result(6,1:60)',(1:60)');
testCase.assertNumElements(testCase.Instance.powerTimeline.Data,60);
end
end
end
3) Finally, if creating these instances independently is expensive (usually they are not) then you can create a single instance that is shared across the class using the TestClassSetup attribute. This is what is known as a shared fixture. I would not recommend using this approach unless creating these objects is expensive, because you end up losing benefits such as order independence and parallelism (among other things). Anyway, this might look like:
classdef testSomeclass < matlab.unittest.TestCase
properties
Instance;
end
methods(TestClassSetup)
function instance = createInstanceFromTestData(testCase)
s = load(fullfile(pwd,'testdata','input.mat'));
id = cell2mat(s.input.ID(3));
year = s.input.Data(3,22);
fueltype = s.input.Data(3,23);
testCase.Instance = Someclass(id,'ccs', year, fueltype);
end
end
methods (Test)
function testInitSomeclass(testCase)
testCase.verifyClass(testCase.Instance,'Someclass');
end
function testSingleAddSamples(testCase)
s = load(fullfile(pwd,'testdata','result.mat'));
testCase.Instance.addSamplesArray('power',s.result(6,1:60)',(1:60)');
testCase.assertNumElements(testCase.Instance.powerTimeline.Data,60);
end
end
end
Hope that helps!

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!