0

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?

Roy Smith
  • 2,039
  • 3
  • 20
  • 27

0 Answers0