Ah, I've got this.  The problem is that pywikibot.Site isn't a class, it's a factory function that returns cached instances of APISite.  It looks like if you want to mock Site, you need to do:

mock_Site = mocker.patch('pywikibot.site.APISite', autospec=True)

or this works too (and is probably cleaner):

mock_Site = mocker.patch('pywikibot.Site', autospec=pywikibot.site.APISite)

I still don't fully understand why my original test passes; mock_Site should have the same attributes as the mocked function, which does not include "xxyyzz", so it should fail.  But I'll just chalk that up to "Every time I finally think I understand how unittest.mock works, I discover something new".



On Nov 29, 2022, at 10:49 AM, Roy Smith <roy@panix.com> wrote:

That's a good observation, thanks, but fixing that doesn't change anything.  This:

def test_ip(mocker):
mock_IPv4Address = mocker.patch('ipaddress.IPv4Address', autospec=True)
ip = mock_IPv4Address('1.2.3.4')
assert ip.xxyyzz

fails in exactly the same way.

On Nov 28, 2022, at 11:01 PM, Dalba <dalba.wiki@gmail.com> wrote:

That does not look like a fair comparison. In `test_ip` you are tryign to get the xxyyzz attribute of the mock object itself, but in `test_site` you're accessing the attribute on the instance of the mock.
I think one of the assertions needs to be changed. Either change ` assert site.xxyyzz ` to ` assert mock_Site.xxyyzz ` or ` assert mock_IPv4Address.xxyyzz ` to ` assert ip.xxyyzz `.

On Tue, Nov 29, 2022 at 5:19 AM Roy Smith <roy@panix.com> wrote:
I've got:

platform darwin -- Python 3.9.13, pytest-7.2.0, pluggy-1.0.0
rootdir: /Users/roy/dev/dyk-tools, configfile: src/pages/pytest.ini
plugins: mock-3.10.0, socket-0.5.1


When I run the following:

def test_ip(mocker):
mock_IPv4Address = mocker.patch('ipaddress.IPv4Address', autospec=True)
ip = mock_IPv4Address('1.2.3.4')
assert mock_IPv4Address.xxyyzz


def test_site(mocker):
mock_Site = mocker.patch('pywikibot.Site', autospec=True)
site = mock_Site('en', 'wikipedia')
assert site.xxyyzz


test_ip() fails, as I expect it to, with AttributeError: Mock object has no attribute 'xxyyzz'.  But, test_site() passes.  WTF?  Why does it not also fail with the same error?

_______________________________________________
pywikibot mailing list -- pywikibot@lists.wikimedia.org
To unsubscribe send an email to pywikibot-leave@lists.wikimedia.org
_______________________________________________
pywikibot mailing list -- pywikibot@lists.wikimedia.org
To unsubscribe send an email to pywikibot-leave@lists.wikimedia.org

_______________________________________________
pywikibot mailing list -- pywikibot@lists.wikimedia.org
To unsubscribe send an email to pywikibot-leave@lists.wikimedia.org