2

I want to ensure that my Class' staticmethod is called with the correct arguments without actually calling it, therefore I am mocking it. E.g.:

import unittest
from unittest.mock import patch

class FooStatic:
    @staticmethod
    def bar_static(self, baz_static):
        print(baz_static)
        pass

class TestFooStatic(unittest.TestCase):
    def test_foo_static(self):
        with patch.object(FooStatic, 'bar_static', autospec=True):
            FooStatic.bar_static()

    def test_foo_static_instance(self):
        with patch.object(FooStatic, 'bar_static', autospec=True):
            foo_s = FooStatic()
            foo_s.bar_static()

Both these tests should complain that FooStatic.bar_static cannot be called without argument 'baz_static'. Unfortunately they don't, the tests succeed.

Without the staticmethod decorator, patch behaves as I expect:

class Foo:
    def bar(self, baz):
        print(baz)
        pass


class TestFoo(unittest.TestCase):
    def test_foo(self):
        with patch.object(Foo, 'bar', autospec=True):
            foo = Foo()
            foo.bar()  # raises TypeError: missing a required argument: 'baz'

I have found a loosely related issue in python, that was fixed from python 3.7 onwards: merged PR. I am on python 3.8.5 (default on ubunutu 20).

I am not opposed to investing some time to try and propose a fix myself. However, I first want to make sure I am not overlooking anything. Any thoughts?

Celmar Y.
  • 301
  • 3
  • 13
  • It seems that `patch` considers that the instance is passed as the first argument to the static method, even if this not the case. If you pass an argument to `bar_static` in your first example, you will get `TypeError: too many positional arguments`. – Neraste May 31 '22 at 08:46

0 Answers0