问题
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