Try to unittest the function to test which used a function with an injected Element I know how to patch the return value of function_to_patch but how to alter the injected element ?
@dataclass
class Element:
type: str
name:str
tags: List[str]
nb_elt:int
def function_to_patch(injected_arg:Element )-> Tuple[List[str], int]:
do_something()
injected_arg.tags=["tag1","tag3"]
return (["somedata"], 0)
def function_to_test()-> str:
injected_arg= Element()
do_something...
mylist, myval = function_to_patch(injected_arg)
....
return Element.tags[1]
With this approach the result is not correct The result does not contain the expected "tag3" as I have no idea on how to alter the injected_arg
@mock.patch("function_to_patch")
def TestsFunctionToTest(self, patch_of_function_to_patch):
patch_of_function_to_patch.return_value=("my return",3)
result = function_to_test()
assertEqual(result, "tag3")
Before to show you my code I add some comments:
@dataclass
so I have removed it from your code.real_patch()
that it is use to execute the patch of the function function_to_patch()
; the body of this function is the same of the body of the function function_to_patch()
with the only difference that it returns (["my return"], 3)
and not (["somedata"], 0)
function_to_test()
adding to it the argument injected_arg
For other changes see the comments in the code
import unittest
from unittest import mock
from typing import List, Tuple
# Commented the decorator
#@dataclass
class Element:
type: str = None # <--- add the init of the attribute
name: str = None # <--- add the init of the attribute
tags: List[str] = [] # <--- add the init of the attribute
nb_elt: int = None # <--- add the init of the attribute
# the following is you function without changes
def function_to_patch(injected_arg: Element) -> Tuple[List[str], int]:
#do_something()
injected_arg.tags = ["tag1", "tag3"]
return (["somedata"], 0)
def function_to_test(injected_arg : Element) -> str:
#injected_arg = Element() # <---- COMMENT this
#do_something...
mylist, myval = function_to_patch(injected_arg)
print(f"mylist = {mylist}, myval = {myval}") # <---- ADDED this print
#....
#return Element.tags[1] # <---- changed the return value
return injected_arg.tags[1]
# my NEW FUNCTION with the return value (["my return"], 3)
def real_patch(injected_arg: Element) -> Tuple[List[str], int]:
#do_something()
injected_arg.tags = ["tag1", "tag3"]
return (["my return"], 3)
class MyTestCase(unittest.TestCase):
@mock.patch(__name__ + "." + "function_to_patch")
def test_injection(self, patch_of_function_to_patch):
injected_arg = Element()
patch_of_function_to_patch.side_effect = [real_patch(injected_arg)] # <--- definition of side_effect and not of return_value
result = function_to_test(injected_arg)
self.assertEqual(result, "tag3")
if __name__ == '__main__':
unittest.main()
The test_injection() method is executed with success on my system:
mylist = ['my return'], myval = 3
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK