Main Content

创建自定义布尔约束

此示例演示如何创建一个自定义布尔约束,该约束确定给定值的大小是否与预期值的大小相同。

在当前文件夹中的一个文件中,创建名为 IsSameSizeAs 的类,该类派生自 matlab.unittest.constraints.BooleanConstraint 类。类构造函数接受预期值,该预期值的大小会与实际值的大小进行比较。预期值存储在 ValueWithExpectedSize 属性中。建议的做法是使 BooleanConstraint 实现不可变,因此将属性 SetAccess 特性设置为 immutable

classdef IsSameSizeAs < matlab.unittest.constraints.BooleanConstraint
    properties (SetAccess=immutable)
        ValueWithExpectedSize
    end
    
    methods
        function constraint = IsSameSizeAs(value)
            constraint.ValueWithExpectedSize = value;
        end
    end  
end

在具有 private 访问权限的 methods 块中,定义辅助方法 sizeMatchesExpected,该方法确定实际值和预期值是否大小相同。该方法由其他约束方法调用。

    methods (Access=private)
        function tf = sizeMatchesExpected(constraint,actual)
            tf = isequal(size(actual), ...
                size(constraint.ValueWithExpectedSize));
        end
    end

matlab.unittest.constraints.BooleanConstraint 类是 matlab.unittest.constraints.Constraint 类的子类。因此,从 BooleanConstraint 类派生的类必须实现 Constraint 类的方法。在 methods 代码块中,实现 satisfiedBygetDiagnosticFor 方法。satisfiedBy 实现必须包含比较逻辑并返回一个逻辑值。getDiagnosticFor 实现必须针对约束对实际值进行计算,并提供 Diagnostic 对象。在此示例中,getDiagnosticFor 返回 StringDiagnostic 对象。

    methods
        function tf = satisfiedBy(constraint,actual)
            tf = constraint.sizeMatchesExpected(actual);
        end

        function diagnostic = getDiagnosticFor(constraint,actual)
            import matlab.automation.diagnostics.StringDiagnostic
            if constraint.sizeMatchesExpected(actual)
                diagnostic = StringDiagnostic("IsSameSizeAs passed.");
            else
                diagnostic = StringDiagnostic( ...
                    "IsSameSizeAs failed." + newline + "Actual Size: [" ...
                    + int2str(size(actual)) + "]" + newline ...
                    + "Expected Size: [" ...
                    + int2str(size(constraint.ValueWithExpectedSize)) ...
                    + "]");
            end
        end
    end

派生自 BooleanConstraint 的类必须实现 getNegativeDiagnosticFor 方法。当约束取反时,此方法必须提供 Diagnostic 对象。在具有 protected 访问权限的 methods 块中实现 getNegativeDiagnosticFor

    methods (Access=protected)
        function diagnostic = getNegativeDiagnosticFor(constraint,actual)
            import matlab.automation.diagnostics.StringDiagnostic
            if constraint.sizeMatchesExpected(actual)
                diagnostic = StringDiagnostic( ...
                    "Negated IsSameSizeAs failed." + newline + ...
                    "Actual and expected sizes were the same ([" ...
                    + int2str(size(actual)) + ...
                    "]) but should not have been.");
            else
                diagnostic = StringDiagnostic( ...
                    "Negated IsSameSizeAs passed.");
            end
        end
    end

为实现必需方法,约束继承相应的 andornot 重载,以便与其他 BooleanConstraint 对象进行组合或求反。

IsSameSizeAs 类定义

这是 IsSameSizeAs 类的完整代码。

classdef IsSameSizeAs < matlab.unittest.constraints.BooleanConstraint
    properties (SetAccess=immutable)
        ValueWithExpectedSize
    end

    methods
        function constraint = IsSameSizeAs(value)
            constraint.ValueWithExpectedSize = value;
        end

        function tf = satisfiedBy(constraint,actual)
            tf = constraint.sizeMatchesExpected(actual);
        end

        function diagnostic = getDiagnosticFor(constraint,actual)
            import matlab.automation.diagnostics.StringDiagnostic
            if constraint.sizeMatchesExpected(actual)
                diagnostic = StringDiagnostic("IsSameSizeAs passed.");
            else
                diagnostic = StringDiagnostic( ...
                    "IsSameSizeAs failed." + newline + "Actual Size: [" ...
                    + int2str(size(actual)) + "]" + newline ...
                    + "Expected Size: [" ...
                    + int2str(size(constraint.ValueWithExpectedSize)) ...
                    + "]");
            end
        end
    end

    methods (Access=protected)
        function diagnostic = getNegativeDiagnosticFor(constraint,actual)
            import matlab.automation.diagnostics.StringDiagnostic
            if constraint.sizeMatchesExpected(actual)
                diagnostic = StringDiagnostic( ...
                    "Negated IsSameSizeAs failed." + newline + ...
                    "Actual and expected sizes were the same ([" ...
                    + int2str(size(actual)) + ...
                    "]) but should not have been.");
            else
                diagnostic = StringDiagnostic( ...
                    "Negated IsSameSizeAs passed.");
            end
        end
    end

    methods (Access=private)
        function tf = sizeMatchesExpected(constraint,actual)
            tf = isequal(size(actual), ...
                size(constraint.ValueWithExpectedSize));
        end
    end
end

测试预期大小

在命令提示符处,创建测试用例以执行交互式测试。

import matlab.unittest.TestCase
import matlab.unittest.constraints.HasLength
testCase = TestCase.forInteractiveUse;

测试一个通过的用例。测试通过,原因是 or 条件之一 HasLength(5) 为 true。

testCase.verifyThat(zeros(5),HasLength(5) | ~IsSameSizeAs(repmat(1,5)))
Verification passed.

测试一个失败的用例。测试失败,原因是 and 条件之一 ~IsSameSizeAs(repmat(1,5)) 为 false。

testCase.verifyThat(zeros(5),HasLength(5) & ~IsSameSizeAs(repmat(1,5)))
Verification failed.
    ---------------------
    Framework Diagnostic:
    ---------------------
    AndConstraint failed.
    --> + [First Condition]:
         |   HasLength passed.
         |   
         |   Actual Value:
         |        0     0     0     0     0
         |        0     0     0     0     0
         |        0     0     0     0     0
         |        0     0     0     0     0
         |        0     0     0     0     0
         |   Expected Length:
         |        5
    --> AND
        + [Second Condition]:
         |   Negated ISameSizeAs failed.
         |   Actual and expected sizes were the same ([5  5]) but should not have been.
        -+---------------------

另请参阅

相关主题