Python Monkey Patch Property
Consider a module with a 'public' function which looks something like this: def func(arg):val = generatesomething(arg)dosomething(val)As you can see this is a 'void function'. Its core logic is in generatesomething.I want to write unit tests for this function. I can think of several approaches to do so.
V/A - UNZIPPING THE ABSTRACT (1980)A1Bathroom Renovations - Intensely Henna'dA2Cajun Cutie - Black Man's WorldA3Dislocation Dance - You Can't Beat HistoryA4Enigma - Play With FireA5Gods Gift - Creeps InA6Hoax - World War IIIA7If Only - If Only.B1Liggers - Pretty GirlB2Mekon - Must Have MoreB3Outer Edge - Old Wives TalesB4Performance - Natural EquilibriumB5Spurtz - Boyfriends Or Your Money BackB6Still - 9.5B7Undercovermen - Of No Fixed AbodeB8Vibrant Thigh - Walking Away. Puke spit and guts rar.
I would like to know what the best one is, both in terms of general programming practices and best practice in Python specifically.Essentialy this question is about the Pythonic way of mocking a private function (money patching? Injecting the function? Injecting an object? I would recommend to use the most simple and shortest approach, which is in Python probably option A,. Everything else makes the code more complicated, with no substantial benefit.
The only thing I would change here is to make this solution more explicit (see below).Converting your module to a class (option C) should be motivated by the fact you need a class instead of a module, not by the fact you want to mock a single function. This option is preferable in languages like Java or C#, where there is no distinction between a 'module' and a 'class' in a way which is comparable to Python, and where a function like func would probably 'live' inside a class at first hand.Replacing the method dosomething by an object with a method (option D) should not be done for the same reason - use an object instead of a standalone function when a standalone function is 'not enough', for the sheer purpose of mocking it brings no advantage.So this leaves you with option B or A.
Pytest Monkeypatch Patch
However, I would not pollute the parameter list of func for the purpose of mocking, nor would I stuff mocking code into a function func just for the purpose of mocking if there is simpler alternative. Better keep the 'official' API as as well the functional code as clean as possible.
Note: OP has significantly edited and changed the question, so this answer is a bit obsolete, but leaving for now for history. Original answer follows:Assuming that generatesomething and dosomething work, and are properly unit tested individually, a good argument can be made not to bother testing func at all.
IMO, it's well past the point of diminishing returns in unit-testing. (Note: If there were many lines of code between the two lines in your example then a test makes sense)For example, your Options B-D, as I understand them, are just a complicated way to test the results of generatesomething, which you could just test directly. Now, maybe they make sense in the overall design of your program, but adding that amount of complexity just for unit tests is a mistake. Thanks for your answer. Two questions: first, generatesomething is a 'private' function, an 'implementation detail', while func is a public function of the module.
Nameerror: Name 'monkeypatch' Is Not Defined
Is it good practice and common to just test generatesomething directly (i.e. Test private methods)?
Secondly, I understand what you mean about func not being wotthwhile to test anyway. But still, I'd like an answer to the question of what is the good and Pythonicbway to mock dosomething.
Which of the four approaches is the best?–Nov 8 '16 at 1:57.