Skip to content
Advertisement

How to employ a MagicMock spec_set or spec on a method?

I am trying to use a method as a spec_set on a MagicMock.

https://stackoverflow.com/a/25323517/11163122 provides a nice example of an unexpected call signature resulting in an Exception. Unfortunately, I can’t get it to work out for a method.

How can I get the below code snippet to error out, given the calls don’t match the spec?

from unittest.mock import MagicMock

class Foo:
    def bar(self) -> None:
        """Some method I want to use as a spec."""

mocking_foo_bar_1 = MagicMock(name="with spec", spec=Foo.bar)
mocking_foo_bar_2 = MagicMock(name="with spec_set", spec_set=Foo.bar)

# These aren't raising, even though they don't match the spec
mocking_foo_bar_1("this", "should", "raise")
mocking_foo_bar_2("this", "also", "should", "raise")

I am using Python 3.8+.

Advertisement

Answer

spec and spec_set are used for limiting the set of attributes a Mock is allowed to access. For functions, there’s create_autospec.

Functions or methods being mocked will have their arguments checked to ensure that they are called with the correct signature.

Since bar is an instance method of Foo, you will also need to create an instance of Foo to get the expected function signature.

from unittest.mock import create_autospec

mocking_foo_bar = create_autospec(Foo().bar)

mocking_foo_bar("this", "should", "raise")

This raises an error:

TypeError: too many positional arguments
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement