Main Content

matlab.unittest.constraints.DictionaryComparator Class

Namespace: matlab.unittest.constraints

Comparator for dictionaries

Since R2022b

Description

The matlab.unittest.constraints.DictionaryComparator class provides a comparator for dictionaries. To use this comparator in your tests, create a DictionaryComparator instance, and specify it as the value of the Using name-value argument of the IsEqualTo constraint constructor.

Creation

Description

c = matlab.unittest.constraints.DictionaryComparator creates a comparator for unconfigured dictionaries. The comparator is satisfied if the actual and expected values are dictionaries with no keys or values.

example

c = matlab.unittest.constraints.DictionaryComparator(comp) uses the specified comparators comp to compare the values contained in the dictionaries. When you use this syntax, the comparator is satisfied if the actual and expected values are dictionaries with the same keys, and the values assigned to corresponding keys satisfy any of the comparators in comp.

example

c = matlab.unittest.constraints.DictionaryComparator(___,Recursively=tf) also specifies whether to operate recursively when comparing the values contained in the dictionaries. If tf is true, the recursion continues until all nested values are examined for equality. You can use this syntax with any of the input argument combinations in the previous syntaxes.

example

Input Arguments

expand all

Comparators used to compare the values contained in the dictionaries, specified as an object array of classes in the matlab.unittest.constraints namespace that are classified as comparators.

Example: matlab.unittest.constraints.NumericComparator

Example: matlab.unittest.constraints.StringComparator(IgnoringCase=true)

Example: [matlab.unittest.constraints.LogicalComparator matlab.unittest.constraints.NumericComparator]

Whether to operate recursively, specified as a numeric or logical 0 (false) or 1 (true).

When the value is true, the values assigned to keys of the actual and expected dictionaries also can be dictionaries, and the comparator recursively compares these values. When the value is false, all values assigned to keys of the actual and expected dictionaries must have a type that is supported by comp. For example, in the following code, both c1 and c2 can compare dictionaries that contain numeric values. However, only c2 can compare dictionaries that contain either dictionaries or numeric values.

import matlab.unittest.constraints.DictionaryComparator
import matlab.unittest.constraints.NumericComparator

c1 = DictionaryComparator(NumericComparator);
c2 = DictionaryComparator(NumericComparator,Recursively=true);

This argument sets the Recursive property.

Properties

expand all

Whether to operate recursively, returned as a logical 0 (false) or 1 (true).

This property is set by the tf input argument.

Attributes:

GetAccess
public
SetAccess
private

Examples

collapse all

Compare actual and expected values using the DictionaryComparator class.

First, import the classes used in this example.

import matlab.unittest.TestCase
import matlab.unittest.constraints.IsEqualTo
import matlab.unittest.constraints.DictionaryComparator
import matlab.unittest.constraints.NumericComparator
import matlab.unittest.constraints.StringComparator

Create a test case for interactive testing.

testCase = TestCase.forInteractiveUse;

Use a DictionaryComparator instance to compare two unconfigured dictionaries with no keys or values. The test passes.

testCase.verifyThat(dictionary,IsEqualTo(dictionary, ...
    Using=DictionaryComparator))
Verification passed.

To compare dictionaries that are configured, pass an appropriate comparator to the DictionaryComparator constructor. For example, compare two dictionaries containing numeric values. The test passes.

d1 = dictionary(["key1" "key2"],[1 2]);
d2 = dictionary("key1",1,"key2",2);
testCase.verifyThat(d1,IsEqualTo(d2, ...
    Using=DictionaryComparator(NumericComparator)))
Verification passed.

Modify one of the dictionaries by introducing a new key-value pair. If you compare the dictionaries again, the test fails because the dictionaries do not have the same keys.

d1("key3") = 4;
testCase.verifyThat(d1,IsEqualTo(d2, ...
    Using=DictionaryComparator(NumericComparator)))
Verification failed.
    ---------------------
    Framework Diagnostic:
    ---------------------
    IsEqualTo failed.
    --> DictionaryComparator failed.
        --> Dictionaries contain different keys.
            --> Extra keys in actual:
                    "key3"
        
        Actual Value:
          dictionary (string --> double) with 3 entries:
        
            "key1" --> 1
            "key2" --> 2
            "key3" --> 4
        Expected Value:
          dictionary (string --> double) with 2 entries:
        
            "key1" --> 1
            "key2" --> 2
    ------------------
    Stack Information:
    ------------------
    In C:\work\CompareValuesUsingDictionaryComparatorExample.m (CompareValuesUsingDictionaryComparatorExample) at 36

Compare nested dictionaries that contain strings by instructing the comparator to operate recursively. The test passes.

group1 = dictionary([1 2],["Andy" "David"]);
group2 = dictionary([1 2 3],["Katia" "Curtis" "Nick"]);
d3 = dictionary("g1",group1,"g2",group2);
d4 = dictionary("g2",group2,"g1",group1);
testCase.verifyThat(d3,IsEqualTo(d4, ...
    Using=DictionaryComparator(StringComparator,Recursively=true)))
Verification passed.

Compare dictionaries with keys whose class overloads the keyHash and keyMatch functions. The testing framework uses the overloaded functions to identify matching dictionary keys when comparing the actual and expected values.

In a file named Match.m in your current folder, create the Match class that overloads the keyHash and keyMatch functions. When objects of the Match class are used as keys, MATLAB ignores the timestamps.

classdef Match
    properties
        Name
        Timestamp
    end
    methods
        function m = Match(name)
            m.Name = name;
            m.Timestamp = datetime;
        end
        function hash = keyHash(m)
            hash = keyHash(m.Name);
        end
        function tf = keyMatch(m1,m2)
            tf = keyMatch(m1.Name,m2.Name);
        end
    end
end

Import the classes used in this example.

import matlab.unittest.TestCase
import matlab.unittest.constraints.IsEqualTo
import matlab.unittest.constraints.DictionaryComparator
import matlab.unittest.constraints.NumericComparator

Create a test case for interactive testing.

testCase = TestCase.forInteractiveUse;

Create two Match objects and compare them using the IsEqualTo constraint. In this example, the test fails because of the different values in the Timestamp property.

m1 = Match("soccer");
pause(1)
m2 = Match("soccer");
testCase.verifyThat(m1,IsEqualTo(m2))
Verification failed.
    ---------------------
    Framework Diagnostic:
    ---------------------
    IsEqualTo failed.
    --> ObjectComparator failed.
        --> The objects are not equal using "isequaln".
        
        Actual Value:
          Match with properties:
        
                 Name: "soccer"
            Timestamp: 21-Apr-2022 14:48:03
        Expected Value:
          Match with properties:
        
                 Name: "soccer"
            Timestamp: 21-Apr-2022 14:48:04
    ------------------
    Stack Information:
    ------------------
    In C:\work\CompareDictionariesWithCustomizedKeyMatchingExample.m (CompareDictionariesWithCustomizedKeyMatchingExample) at 36

Create two dictionaries that contain the same numeric value using m1 and m2 as keys, and then compare the dictionaries. Even though m1 and m2 are not equal due to different values of the Timestamp property, the test passes because the framework treats m1 and m2 as the same key.

d1 = dictionary(m1,2022);
d2 = dictionary(m2,2022);
testCase.verifyThat(d1,IsEqualTo(d2, ...
    Using=DictionaryComparator(NumericComparator)))
Verification passed.

Tips

  • In most cases, you are not required to use a DictionaryComparator instance. The IsEqualTo class creates a constraint to test for the equality of various data types, including dictionaries.

    Use a DictionaryComparator instance when you need to override the comparison performed by the IsEqualTo class. For example, if you want the comparison to fail when dictionaries contain nonnumeric values, include a DictionaryComparator instance in your test. In this example, MATLAB® throws an error because the actual and expected dictionaries contain nonnumeric values assigned to their keys.

    import matlab.unittest.TestCase
    import matlab.unittest.constraints.IsEqualTo
    import matlab.unittest.constraints.DictionaryComparator
    import matlab.unittest.constraints.NumericComparator
    
    testCase = TestCase.forInteractiveUse;
    exp = dictionary([1 2 3],[true true false]);
    act = exp;
    testCase.verifyThat(act,IsEqualTo(exp,Using=DictionaryComparator(NumericComparator)))
    

Version History

Introduced in R2022b