How do I create two different mocked objects with the same spec using the patch decorator?
I have a test that needs two mocked selenium WebElements. I could just use two patch decorators:
@mock.patch("selenium.webdriver.remote.webelement.WebElement")
@mock.patch("selenium.webdriver.remote.webelement.WebElement")
def test_does_not_match_unclickable_element(
self, invisible_element, inactive_element
):
But in this case, I want to ensure the patched objects are specced out so that any code that might try to call a non-existent method will fail properly.
@mock.patch("selenium.webdriver.remote.webelement.WebElement", autospec=True)
@mock.patch("selenium.webdriver.remote.webelement.WebElement", autospec=True)
def test_does_not_match_unclickable_element(
self, invisible_element, inactive_element
):
invisible_element.is_displayed.return_value = False
invisible_element.is_enabled.return_value = True
inactive_element.is_displayed.return_value = True
inactive_element.is_enabled.return_value = False
The following exception raises:
unittest.mock.InvalidSpecError: Cannot autospec attr 'WebElement' from target 'selenium.webdriver.remote.webelement' as it has already been mocked out. [target=<module 'selenium.webdriver.remote.webelement' from '/python3.10/site-packages/selenium/webdriver/remote/webelement.py'>, attr=<MagicMock name='WebElement' spec='WebElement' id='4501588480'>]
How do I pass two copies of the patch mocked object to my test?
Edit:
I could use the spec
argument directly which has similar results (and would ultimately solve the problem) but....
# This works
@mock.patch("selenium.webdriver.remote.webelement.WebElement", spec=WebElement)
@mock.patch("selenium.webdriver.remote.webelement.WebElement", spec=WebElement)
def test_does_not_match_unclickable_element(
self, invisible_element, inactive_element
):
I'd like to understand how I can solve the problem utilizing the autospec
argument.