3

I'm using the mock library and unittest2 in order to test different aspects of my software project.

At the moment I have the following question: is it possible to mock a function so that the default keyword argument is different, but the functionality remains?

Say I have the following code

class C(): def fun(self, bool_arg = True): if bool_arg: return True else return False 

What if I want to mock C.fun:

C.fun = mock.Mock(???) 

so that every instance of C will replace keyword 'bool_arg' with False, instead of True and the result of:

c = C() c.fun() 

returns:

False

0

2 Answers 2

3

you can also try to wrap your function. Something on the line of

def wrapper(func, bool_arg): def inner(*args, **kwargs): kwargs['bool_arg']=bool_arg return func(*args, **kwargs) return inner 

and

class C(): def fun(...): ... c = C() c.fun = wrapper(fun, False) 

should work

Edit

If you want to change the default for the class and not for a particular instance you can create a derived class and redefine fun wrapping the method of C. Something on the line (I don't have now the time to test it):

class D(C): def fun(self, *args, **kwargs): f = wrapper(C.f, False) return f(*args, **kwargs) 

Then about the suggestion of @Ber, you can define def wrapper(func, **wrapkwargs) and then instead of kwargs['bool_arg']=bool_arg do

for i in wrapkwargs.iteritems(): #wrapkwargs is a dictionary kwargs[i[0]] = i[1] 
Sign up to request clarification or add additional context in comments.

8 Comments

Nice. Thid could be extended to wrap any function, supplying any list of keyword args.
Thanks for your answer! I was actually looking for replacing the Class default keyword argument to be replaced for every instance of it. But I adapted your solution a little so that instead of: c.fun = wrapper(...) I did: class C.fun = wrapper(...). And it worked for all instances!
Ber, how would you generalize the above to accept any keyword argument that one wants to wrap ?
@mpaf you mean that you have changed the implementation of class C substituting self.fun with a wrapped version?
@mpaf: if you want to get a better understanding of wrapper (and consequently decorators) I suggest you to read stackoverflow.com/a/1594484/1860757 and simeonfranklin.com/blog/2012/jul/1/…
|
2

You can try to use this code:

>>> import mock >>> >>> class C(): ... def fun(self, bool_arg = True): ... if bool_arg: ... print "True" ... else: ... print "False" ... >>> c = C() >>> funCopy = c.fun >>> c.fun = mock.Mock(side_effect=lambda bool_arg=False: funCopy(bool_arg=bool_arg)) >>> c.fun() False 

Hope this helps

5 Comments

Did not know that you could do default variable assignment inside a lambda.
@jdotjdot You are right, but I think if mpaf make this question is because he can call the function changing the default variable value.
@jdotjdot in english please
@jdotjdot OK! no problem, and sorry for my english ;)
Thanks for this solution, I would have accepted it as it was the first one, but I couldn't make it work for the case that I was looking for (maybe I wasn't too explicit in my question) which was that every instance of class C gets that keyword argument replaced.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.