Python's assert_called_with, is there a wildcard character?
assert, mocking, python, testing
Solution
If you're calling `sendmail` with a named parameter `subject` then it's better to check whether the named argument matches what you expect:
args, kwargs = self.myclass.sendmail.call_args
self.assertEqual(kwargs['subject'], "Hello World")
This does assume both implementations of `sendmail` have a named parameter called `subject`. If that's not the case you can do the same with a positional parameter:
args, kwargs = self.myclass.sendmail.call_args
self.assertTrue("Hello World" in args)
You can be explicit about the position of the argument (i.e., the first argument or the third argument that's passed to `sendmail` but that depends on the implementation of `sendmail` being tested).
Problem
Suppose I have a class in python set up like this. ``` from somewhere import sendmail class MyClass: def __init__(self, **kargs): self.sendmail = kwargs.get("sendmail", sendmail) #if we can't find it, use imported def def publish(): #lots of irrelevant code #and then self.sendmail(mail_to, mail_from, subject, body, format= 'html') ``` So as you can see, I have sort of given myself the option to parameterize which function I use for self.sendmail Now in the test file. ``` Class Tester(): kwargs = {"sendmail": MagicMock(mail_from= None, mail_to= None, subject= None, body= None, format= None)} self.myclass = MyClass(**kwargs) ##later on def testDefaultEmailHeader(): default_subject = "Hello World" self.myclass.publish() self.myclass.sendmail.assert_called() #this is doing just fine self.myclass.sendmail.assert_called_with(default_subject) #this is having issues ``` For some reason I am getting the error message ``` AssertionError: Expected call: mock('Hello World') Actual Call : mock('defaultmt', 'defaultmf', 'Hello World', 'default_body', format= 'html') ``` So basically, the assert is expecting sendmail to be called with only one variable, when it ends up being called with all 5. The thing is, I don't care about what the other 4 variables are! I just want to make sure it is called with the correct subject. I tried the mock place holder ANY, and got the same thing ``` self.myclass.sendmail.assert_called_with(ANY, ANY, 'Hello World', ANY, ANY) AssertionError: Expected call: mock(<ANY>, <ANY>, 'Hello World', <ANY>, <ANY>) Actual Call : mock('defaultmt', 'defaultmf', 'Hello World', 'default_body, 'format= 'html') ``` Really unsure on how to proceed with this one. Anyone have any advice if we only care about one of the variable and want to ignore the rest?