Python unittest's assertDictContainsSubset recommended alternative

python, python-3.x, unit-testing

Solution

On Python 3.9+, use the dictionary union operator.

Change

assertDictContainsSubset(a, b)

to

assertEqual(b, b | a)

On older versions of Python, change it to

assertEqual(b, {**b, **a})

Note the order of the arguments, `assertDictContainsSubset` put the "larger" dictionary (`b`) second and the subset (`a`) first, but it makes more sense to put the larger dictionary (`b`) first (which is why `assertDictContainsSubset` was removed in the first place).

This creates a copy of `b` then iterates over `a`, setting any keys to their value in `a` and then compares that result against the original `b`. If you can add all the keys/values of `a` to `b` and still have the same dictionary, it means `a` doesn't contain any keys that aren't in `b` and all the keys it contains have the same values as they do in `b`, i.e. `a` is a subset of `b`.

Problem

I have some tests in Python written in unittest. I want to check that some of my dictionaries contain at least certain attributes equal to certain values. If there are extra values, that would be fine. `assertDictContainsSubset` would be perfect, except that it's deprecated. Is there a better thing that I should be using or should I just recursively assert the contents to be equal if they are in the target dictionary? The docs recommend using `addTypeEqualityFunc`, but I do want to use the normal `assertEqual` for dicts in some cases.

Original source

Related problems