我正在开发一个具有以下类的层次结构的项目:
images.example.com
example-bucket.s3-website-us-west-1.amazonaws.com
% Standard class that has properties and methods shared by all classes in the project
classdef StandardClass < handle
properties (Constant, Abstract)
displayName
end
end
使用这个MWE,我可以创建具体类的实例,我可以查询displayName。
现在,我想测试与我的% Abstract class that defines the interface for a particular set of concrete classes
classdef AbstractClass < StandardClass
methods
function name = getDisplayName(obj)
name = obj.displayName;
end
end
end
接口的另一个类。我不想编写循环遍历每个具体类并测试界面的测试,而是想使用新的模拟框架使用我的% Actual implementation of the concrete class
classdef ConcreteClass < AbstractClass
properties (Constant)
displayName = 'My Concrete Class'
end
end
作为模板进行模拟:
AbstractClass
以错误结束:
AbstractClass
嗯,那真是太糟糕了。不过我想我明白了。模拟器无法知道如何分配抽象属性,所以我添加:
classdef UnitTest < matlab.mock.TestCase
methods (Test)
function testDisplay(obj)
concrete = createMock(obj, ?AbstractClass);
% My test here
end
end
end
到我的---------
Error ID:
---------
'MATLAB:mock:MockContext:NonDefaultPropertyAttribute'
--------------
Error Details:
--------------
Error using matlab.mock.internal.MockContext>validateAbstractProperties (line 623)
Unable to create a mock for the 'AbstractClass' class because Abstract property 'displayName' has a non-default value for its 'Constant' attribute.
。然后当我运行我的测试时,我的模拟器被创建并且单元测试运行良好。但是,如果我然后去尝试在测试框架之外创建具体类:
properties (Constant)
displayName = 'Abstract Class';
end
所以我陷入了困境22。我可以让模拟工作并成功运行单元测试,只有当我打破代码使它不能运行时。
我正在使用的代码库有很多基于我们标准类的抽象类。有没有办法告诉模拟框架在使用模板调用AbstractClass
时如何分配>> test = ConcreteClass();
Error using ConcreteClass
Cannot define property 'displayName' in class 'ConcreteClass' because the property has already been defined in the superclass 'AbstractClass'.
属性?
答案 0 :(得分:2)
编辑:从MATLAB R2018a开始,可以使用'DefaultPropertyValues'
名称/值对和createMock
方法。
例如:
classdef UnitTest < matlab.mock.TestCase
methods (Test)
function testDisplay(testCase)
concrete = createMock(testCase, ?AbstractClass, ...
'DefaultPropertyValues',struct('displayName','Abstract Class'));
% My test here
end
end
end
有关详细信息,请参阅相关文档页面: https://www.mathworks.com/help/matlab/ref/matlab.mock.testcase.createmock.html?searchHighlight=DefaultPropertyValues
正如您所发现的,没有办法为具有Abstract,Constant属性的类创建模拟,但这是我们将在未来版本中考虑的功能。
这是一种解决方法:
从MATLAB R2017b开始,您可以使用Abstract,Static方法为类创建模拟: https://www.mathworks.com/help/matlab/release-notes.html?searchHighlight=Mocking%20Framework%3A&s_tid=doc_srchtitle
因此,您可以重新构造代码以使用Static方法而不是Constant属性:
% Standard class that has properties and methods shared by all classes in the project
classdef StandardClass < handle
methods (Abstract, Hidden, Static)
name = getDisplayNameInternal
end
end
% Abstract class that defines the interface for a particular set of concrete classes
classdef AbstractClass < StandardClass
methods
function name = getDisplayName(obj)
name = obj.getDisplayNameInternal;
end
end
end
% Actual implementation of the concrete class
classdef ConcreteClass < AbstractClass
methods (Hidden, Static)
function name = getDisplayNameInternal
name = 'My Concrete Class';
end
end
end
然后您可以创建一个模拟:
[concrete, behavior] = createMock(obj, ?AbstractClass);
assignOutputsWhen(obj, withAnyInputs(behavior.getDisplayNameInternal), 'My mock class');
实现了所需的行为:
>> concrete.getDisplayName
ans =
'My mock class'