I'm using:
platform darwin -- Python 3.9.13, pytest-7.2.0, pluggy-1.0.0
plugins: mock-3.10.0, socket-0.5.1
pywikibot 7.7.1
I want to mock pywikibot.Site. Surprisingly, this test passes:
def test_site_autospec(mocker, capsys):
mock_Site = mocker.patch('pywikibot.Site', autospec=True)
site = mock_Site('en', 'wikipedia')
assert site.non_existant_function()
I expected it to fail with an AttributeError because non_existant_function() doesn't exist. It turns out, Site isn't a class, but a factory function which returns a (possibly cached) pywikibot.site.APISite instance. If I explicitly use the underlying APISite class as the spec source:
def test_site_autospec_with_obejct(mocker, capsys):
mock_Site = mocker.patch('pywikibot.Site', autospec=pywikibot.site.APISite)
site = mock_Site('en', 'wikipedia')
assert site.non_existant_function()
that fails as expected:
E AttributeError: Mock object has no attribute 'non_existant_function'
but I don't understand what's going on with the first test. I get that the test is not written correctly, but why does it pass? The mock that's created should have the same attributes as the factory function. The function doesn't have a non_existant_function attribute, so neither should the mock, and I should get an AttributeError. This is exactly the kind of broken tests that autospec is supposed to protect you from, no?