Search code examples
python-3.xunit-testingmockingwildcardassert

How do I wildcard a string when I'm asserting a method is called with it? Python3 mock


When using mock's call() objects with assert_has_calls, I'm struggling to assert a given string has been used with an unknown value appended to the end.

For example:

Code under test:

mystring = 'a known string with an unknown value: {0}'.format(unknown_value)
method_to_call(mystring)

Current test code:

with mock.patch('method_to_call') as mocked_method:
  calls = [call('a known string with and unknown value: {0}'.format(mock.ANY)]
  call_method()
  mocked_method.assert_has_calls(calls)

This gives me something along the lines of:

AssertionError: Calls not found.
Expected: [call('a known string with and unknown value: <ANY>')]

How can I assert that the given string has been passed to the method but allow for the unknown value?


Solution

  • You can use the callee lib to do partial matching on the string that is used in the method call:

    from callee import String, Regex
    
    with mock.patch('method_to_call') as mocked_method:
        call_method()
        mocked_method.assert_called_with(String() & Regex('a known string with an unknown value: .*'))
    

    Alternatively, if you don't want to add another lib and you're sure that you know the order of the calls, you can extract the string from the call args and then match using regex

    import re
    
    with mock.patch('method_to_call') as mocked_method:
      call_method()
      argument_string = mocked_method.call_args[0][0]
    
      pattern = re.compile("a known string with an unknown value: .*")
      assert pattern.match(argument_string)