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

mocker fixture cannot be used in module scope #136

Closed
aleGpereira opened this issue Feb 20, 2019 · 13 comments · Fixed by #182
Closed

mocker fixture cannot be used in module scope #136

aleGpereira opened this issue Feb 20, 2019 · 13 comments · Fixed by #182

Comments

@aleGpereira
Copy link

If i define a custom fixture like:

@pytest.fixture(scope='module')
def my_fixture(mocker):
// code using mocker

class TestMyModule(object):

def test_one(self, my_fixture):
    // test code

When i run this i get:
ScopeMismatch: You tried to access the 'function' scoped fixture 'mocker' with a 'module' scoped request object, involved factories

I'm i doing something wrong to do something like this? is there some reason why this is not supported?

Thanks.

@nicoddemus
Copy link
Member

Hi @aleGpereira,

This is a pytest limitation I'm afraid, mocker is a function-scoped fixture so it cannot be used in higher scopes.

A proposal for a new "invocation-scoped" fixture is proposed in pytest-dev/pytest#1681, but the implementation for that has been pulled back because we encountered some severe problems with the implementation right before a release.

For your module-scope fixture, an alternative is to fallback is the unittest.mock module directly, using a with statement.

Cheers,

@schollii
Copy link

schollii commented Apr 16, 2019

A major reason for using mocker is to avoid 4-level deep "with" blocks when patching multiple functions; often using "with" is not very nice. I use the following trick: instead of using nested "with" statements, I define a nest function because I can then define the "mock.patch" as decorators. So instead of:

def test_something(): 
    ...
    with mock.patch(...): 
        with mock.patch(...):
            with mock.patch(...):
                with mock.patch(...):
                     ...

I use this:

def test_something(): 
    ...
    @mock.patch(...)
    @mock.patch(...)
    @mock.patch(...)
    @mock.patch(...)
    def inner_func(_1, _2, _3, _4):
        ...

This is better but the nice thing with mocker, is you don't have to worry about additional call params which you may not even care about (often _1, _2 etc are not used).

So it would be nice to enable mocker to be used in different scopes. How about a mocker_each_func, mocker_each_cls, mocker_each_mod, etc? Just define a few additional mockers, one for each scope, might be simpler than one mocker that adapts.

@schollii schollii reopened this Apr 16, 2019
@matthewatabet
Copy link

A simple solution to this could be to provide mocker_session and mocker_module fixtures.

@doandzhiFt
Copy link

Greetings! Is there any progress with this one?

@nicoddemus
Copy link
Member

Hi @doandzhiFt,

Not really I'm afraid, but I will gladly review and merge a PR that adds mock_session, mock_class and mock_module fixtures. 😁

scorphus added a commit to scorphus/pytest-mock that referenced this issue Apr 13, 2020
While the feature proposed in pytest-dev/pytest#1681 is interesting and
would serve as base for a more elegant solution to pytest-dev#136, adding those
supplementary mockers allows this plugin to be used in other scopes.

Fix pytest-dev#136
scorphus added a commit to scorphus/pytest-mock that referenced this issue Apr 13, 2020
While the feature proposed in pytest-dev/pytest#1681 is interesting and
would serve as a base for a more elegant solution to pytest-dev#136, adding those
supplementary mockers allows this plugin to be used in other scopes.

Fix pytest-dev#136
@scorphus
Copy link
Contributor

Ping, @nicoddemus

@nicoddemus
Copy link
Member

Hi @scorphus, sorry for the delay.

I've just merged your patch and will make a release shortly, thanks a lot for the contribution, I appreciate it greatly. 👍

@nicoddemus
Copy link
Member

Published in 3.1.0, thanks!

@aleGpereira
Copy link
Author

Great work, thanks guys!

@scorphus
Copy link
Contributor

scorphus commented Apr 18, 2020

Glad it's useful to you too, @aleGpereira!

Thanks again for the new release, @nicoddemus!

Open source is amazing! Just a few days ago I tried to use mocker in a session-scoped fixture and found this issue. This coming week there's going to be code on production tested by a session-scoped fixture using session_mocker YAY 🎉🙌

@huaxlin
Copy link

huaxlin commented Dec 7, 2021

I had the same problem.

according to this issue, fixed it with module_mocker. 🎉

@pawelad
Copy link

pawelad commented Mar 7, 2024

It would be good to mention this in the docs - I'll try to open a PR when I have some time.

@pawelad
Copy link

pawelad commented Mar 11, 2024

It would be good to mention this in the docs - I'll try to open a PR when I have some time.

Actually, it's already in there, I just somehow missed it (twice?):

It is also possible to use mocking functionality from fixtures of other scopes using
the appropriate fixture:
* ``class_mocker``
* ``module_mocker``
* ``package_mocker``
* ``session_mocker``

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

Successfully merging a pull request may close this issue.

8 participants