How can I ignore certain values when comparing dictionaries in unittest?

左心房为你撑大大i 提交于 2020-01-15 11:45:07

问题


I would like to assert that two dictionaries are equal, using Python's unittest, but ignoring the values of certain keys in the dictionary, in a convenient syntax, like this:

from unittest import TestCase

class Example(TestCase):
    def test_example(self):
        result = foobar()
        self.assertEqual(
            result,
            {
                "name": "John Smith",
                "year_of_birth": 1980,
                "image_url": ignore(), # how to do this?
                "unique_id": ignore(), #
            },
        )

To be clear, I want to check that all four keys exist, and I want to check the values of "name" and "year_of_birth", (but not "image_url" or "unique_id"), and I want to check that no other keys exist.

I know I could modify result here to the key-value pairs for "image_url" and "unique_id", but I would like something more convenient that doesn't modify the original dictionary.

(This is inspired by Test::Deep for Perl 5.)


回答1:


There is unittest.mock.ANY which compares equal to everything.

from unittest import TestCase
import unittest.mock as mock

class Example(TestCase):
    def test_happy_path(self):
        result = {
            "name": "John Smith",
            "year_of_birth": 1980,
            "image_url": 42,
            "unique_id": 'foo'
        }
        self.assertEqual(
            result,
            {
                "name": "John Smith",
                "year_of_birth": 1980,
                "image_url": mock.ANY,
                "unique_id": mock.ANY
            }
        )

    def test_missing_key(self):
        result = {
            "name": "John Smith",
            "year_of_birth": 1980,
            "unique_id": 'foo'
        }
        self.assertNotEqual(
            result,
            {
                "name": "John Smith",
                "year_of_birth": 1980,
                "image_url": mock.ANY,
                "unique_id": mock.ANY
            }
        )

    def test_extra_key(self):
        result = {
            "name": "John Smith",
            "year_of_birth": 1980,
            "image_url": 42,
            "unique_id": 'foo',
            "maiden_name": 'Doe'
        }
        self.assertNotEqual(
            result,
            {
                "name": "John Smith",
                "year_of_birth": 1980,
                "image_url": mock.ANY,
                "unique_id": mock.ANY
            }
        )

    def test_wrong_value(self):
        result = {
            "name": "John Smith",
            "year_of_birth": 1918,
            "image_url": 42,
            "unique_id": 'foo'
        }
        self.assertNotEqual(
            result,
            {
                "name": "John Smith",
                "year_of_birth": 1980,
                "image_url": mock.ANY,
                "unique_id": mock.ANY
            }
        )



回答2:


You can simply ignore the selected keys in the result dictionary.

self.assertEqual({k: v for k, v in result.items()
                  if k not in ('image_url', 'unique_id')},
                 {"name": "John Smith",
                  "year_of_birth": 1980})


来源:https://stackoverflow.com/questions/57624731/how-can-i-ignore-certain-values-when-comparing-dictionaries-in-unittest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!