MarkBerlin78 / pymox

Automatically exported from code.google.com/p/pymox
Apache License 2.0
0 stars 0 forks source link

Optional arguments #37

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Related to issue 12, I want to stub out a function with optional arguments. I 
can't know in advance whether the optional arguments will be provided or not.
IgnoreArg() is no help with missing arguments.

def bar(one, two=None):
  pass

The test subject may call
bar(1)
or
bar(1, two=None)
or
bar(1, None)
or
bar(1, 42)

I'd like to be able to do
bar(1, two=IgnoreArg())
and have it match all of the above.

Original issue reported on code.google.com by stefano.rivera on 16 Aug 2011 at 9:12

GoogleCodeExporter commented 9 years ago
Mox is intended to be used for deterministic tests.

Why can't you know in advance what your code is going to do?

Original comment by steve.mi...@gmail.com on 16 Aug 2011 at 3:52

GoogleCodeExporter commented 9 years ago
OK, I only really need the first two examples above.

I have to stub out a function in another library for a test, and there are 
multiple versions of this library in production. The new version passes 
two=None, the other doesn't.

Original comment by stefano.rivera on 16 Aug 2011 at 4:17

GoogleCodeExporter commented 9 years ago
> Why can't you know in advance what your code is going to do?

Because Python, that's why!:D

The code under test may start off calling the mocked API without a given arg 
– relying on the default value defined in that API, and then change to pass 
the arg explicitly, with the same value as the arg's default, or vice versa. In 
the real system it wouldn't change the behavior, but it breaks a Mox test – 
creating negative value from the unnecessarily brittle test.

The point here is Python-the-language has a feature "default arg value", 
meaning that passing the arg explicitly with that value or skipping it, has the 
same effect at runtime. Mox does not allow to specify that semantics in a 
mocked call.

A practical example. I am testing an API that makes RPC calls underneath, and I 
want to mock and verify that it makes the right RPC calls. The RPC stubs that I 
am mocking out, take an optional argument (default value None) that I don't 
care about in the unit tests. I have a unit test that verifies a retry after an 
RPC timeout. It so happens that the first call passes the optional arg that I 
don't care about, and the retried calls don't. Yes it is formally deterministic 
in the sense that I can mock these out, but at that point I'd be testing the 
implementation not the interface, in a brittle way – if the implementation 
changes to always pass the arg explicitly (as in fact it just did), my tests 
break, with no benefit to me as the test owner, only meaningless maintenance to 
adjust the test expectations that have nothing to do with the real system 
behavior, but are only an artifact of how Mox works.

Original comment by k...@google.com on 22 Sep 2015 at 3:13