Hi Daniel,

On 10/23/2013 11:30 AM, Daniel Nouri wrote:
> I have a function 'somefunc' in module 'a'.  Another module 'b' imports
> that function with a "from import":
> 
> a.py:
> 
>   def somefunc():
>       return 'hey!'
> 
> b.py:
> 
>   from a import somefunc
> 
>   def someotherfunc():
>       return somefunc() + 'there'
> 
> 
> I want to now test 'someotherfunc' while patching away 'somefunc':
> 
>   def test_someotherfunc(monkeypatch):
>       from b import someotherfunc
>       monkeypatch.setattr('a.somefunc', lambda: 'eh?')
>       someotherfunc()

This doesn't look like correct syntax for monkeypatch.setattr. I think
you mean:

    monkeypatch.setattr(a, 'somefunc', lambda: 'eh?')

> But this will fail, since 'b' imported somefunc from 'a' before we
> monkey patched the module's attribute.  Without a "from import", this
> would work:
> 
> b.py:
> 
>   import a
> 
>   def someotherfunc():
>       return a.somefunc() + 'there'
> 
> What I would normally resort to is patch somefunc's func_code, so that
> even code that used a "from import" before I could patch will use the
> patched version.
> 
> Thoughts?

The simpler approach is to patch in the module where the function is
used, not the module where it is defined. This has the added advantage
of limiting the scope of your monkeypatching to only the module where
you actually need it. So monkeypatch b.somefunc instead of a.somefunc:

    monkeypatch.setattr(b, 'somefunc', lambda: 'eh?')

The key point here is to think of monkeypatching as just "reassign some
name in some namespace", which makes it natural to reassign the name
within the namespace where your code-under-test is actually using the name.

Carl
_______________________________________________
Pytest-dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pytest-dev

Reply via email to