Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can I mock a function in the called script? #40

Closed
carmocca opened this issue Oct 16, 2020 · 5 comments
Closed

Can I mock a function in the called script? #40

carmocca opened this issue Oct 16, 2020 · 5 comments

Comments

@carmocca
Copy link

Im having trouble mocking a function in the script im calling. Is it possible?

file: foo.py

def func(x):
    raise Exception

if __name__ == "__main__":
    func('works!')

file: test.py

import foo

def test(script_runner, monkeypatch):
    monkeypatch.setattr(foo, "func", lambda x: print(x))

    # this does print
    foo.func("mocked function!")

    ret = script_runner.run("foo.py")

    # however, this does not work, an exception is raised
    assert ret.success

Thank you.

@kvas-it
Copy link
Owner

kvas-it commented Oct 16, 2020

It should work in in-process mode but not in subprocess mode (because in that case you're starting a separate process so the mocking won't apply). To ensure your test runs in in-process mode you can add this decorator to it:

@pytest.mark.script_launch_mode('inprocess')

Let me know if this doesn't work. This would be a bug that I'd want to fix.

@carmocca
Copy link
Author

Isn't inprocess the default launch mode? In any case, it still does not work when I set it explicitly

@kvas-it
Copy link
Owner

kvas-it commented Oct 16, 2020

Yeah, you're right, mocking in the script itself doesn't work even in in-process mode. The reason for that is that the script is not imported via the usual module machinery but is compiled and executed directly instead. There are two problems with importing it as a module:

  1. it might not be accessible (not in the path and/or not a .py file),
  2. if we import it as a module, __name__ will not be "__main__", so if __name__ == '__main__': block that many scripts have would not execute, which would mess things up.

It's possible to work around (1), at least we could use the module if it is importable, but I don't see a way to work around (2) without lots of hacks that I'd rather not go into.

If it helps, you can import other modules into the script and mock objects in those modules. Any module that you can import into the script and into the test you can mock (and I added a test for this now), just not the script itself.

@carmocca
Copy link
Author

I figured it was a hard limitation. Thanks for the quick response!

Also, great job on the plugin 👍

@kvas-it
Copy link
Owner

kvas-it commented Oct 16, 2020

Also, great job on the plugin 👍

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants