Writing some unit tests in python and using MagicMock to mock out a method that accepts a JSON string as input. In my unit test, I want to assert that it is called with given arguments, however I run into issues with the assert statement, since the ordering of objects within the dict doesn't matter, besides in the assert statement for the string. Simplified example of what I am trying to achieve below.
mock_funct = MagicMock()
# mocked function called elsewhere
expected = {"a":"a", "b":"b"}
mock_funct.assert_called_once_with(json.dumps(expected))
The above may pass or may fail due to the arbitrary ordering of the keys within the dict when it is dumped to json, ie both '{"a":"a", "b":"b"}'
and '{"b":"b", "a":"a"}'
are valid dumps but one would fail and one would pass, however I would like to write the test so that either would pass.
Unfortunately, you'll need to do your own checking here. You can get the calls from the mock via it's call_args_list
attribute (or, simply call_args
in this case since you have already asserted that it is called only once). I'll assume you're using unittest
in my example code -- but it should be easy enough to adapt for any testing framework ...
mock_funct.assert_called_once_with(mock.ANY)
call = mock_funct.call_args
call_args, call_kwargs = call # calls are 2-tuples of (positional_args, keyword_args)
self.assertEqual(json.loads(call_args[0]), expected)
I've still used assert_called_once_with
to make sure that the function was only called once with a single positional argument, but then I open up the call to look at that argument to check that it is correct.