pytest has this example in the monkeypatching docs:
import os.path
def getssh(): # pseudo application code
return os.path.join(os.path.expanduser("~admin"), '.ssh')
def test_mytest(monkeypatch):
def mockreturn(path):
return '/abc'
monkeypatch.setattr(os.path, 'expanduser', mockreturn)
x = getssh()
assert x == '/abc/.ssh'
When I remove the path
argument from the mockreturn
function, I get the error
def getssh(): # pseudo application code
> return os.path.join(os.path.expanduser("~admin"), '.ssh')
E TypeError: mockreturn() takes 0 positional arguments but 1 was given
I don't understand what is providing that positional argument?
Also, when I reimplement the same thing for pathlib.Path.home() I cannot have this argument path
there, otherwise it won't work. Unfortunately, the documentation does not say anything about that ominous path
argument.
Any illumination for what magic is happening here would be very helpful!
You're trying to replace
os.path.expanduser
that takes one argument with a mock that doesn't take arguments at all which results to an error when called. Under the hoodmonkeypatch.setattr
uses builtinsetattr
so the original version is basically doing following which works since bothexpanduser
andmock
take single argument:Now if you try to replace
expanduser
with a method that doesn't take arguments and keep calling it the same way you'll get an error:Note that you'll get exactly the same error if you try to call
mock
directly: