I have this file with unit tests:
#file tests.py
class TestResults(TestBase): ...
class TestRegisteredFunctions(TestBase):
"""Tests functions registered dynamically."""
def testNewFunction(self):
"""Server must register new functions."""
# Register new function
def square(num):
return num * num
self.server.register('square', square)
res = self.jsonrpc_req(1, 'square', [2])
self.assertEqual(res['result'], 4)
Most of the code is omitted because will not be relevant.
My problem is I need to grab that "square" function.
For example doing getattr(tests, 'square') in another module would correctly get me that square function. How can I achieve such result?
Related
I want to test a file called ninja.py wrote in Python3.6.
# File ninja.py
def what_to_do_result(result):
# Send a mail, write something in a file, play a song or whatever
def my_function(a, b):
# Step 1
result = a + b
# Step 2
if result == 3:
what_to_do_result(result)
elif result == 5:
what_to_do_result(result + 1)
else:
return True
I have started writing a test file called test_ninjapy and wrote some unittest. I do use Pytest.
import pytest
class MyTestException(Exception):
pass
def run_side_effect(*args, **kwargs):
raise MyTestException(kwargs["result"])
#pytest.fixture(name="resource")
def setup_fixture():
# Some code here
class TestNinja:
#staticmethod
def setup_method():
# Function called before each test
#staticmethod
def teardown_method():
# Function called after each test
#staticmethod
def test_my_function(mocker, resource):
# How to do this ???
mocker.patch("ninja.what_to_do_result", return_value=None, side_effect=run_side_effect)
# Then the test
assert 1 == 1 # -> This works
with pytest.raises(MyTestException):
ninja_function(a=1, b=2)
assert ninja_function(a=5, b=10)
The point is that I want to mock the function ninja.what_to_do_result and apply a side effect (= run a function).
I want the side effect to use the parameter (kwargs) or the function what_to_do_result.
But I don't know how to do this.
For example:
Because there are multiple possibilities (in the step 2, the call of what_to_do_result could be with 3 & 5, which are linked with 2 differents use cases I wxant to test.
Can you help me?
I did not found the related section in the documentation below.
Link to the documentation: https://github.com/pytest-dev/pytest-mock
I need to patch a function imported from the same file containing another function I want to test, but it's not working =/.
# funcs.py
def func_one():
return 1
def func_two():
return func_one() + 2
from .funcs import func_two
class TestFunc(TestCase):
def test_func_two(self):
with patch('func_one', 0):
result = func_two()
The result should be two but I got an error with the test:
TypeError: Need a valid target to patch. You supplied: 'func_one'
I need to import the absolute path of the function:
from .funcs import func_two
class TestFunc(TestCase):
def test_func_two(self):
#patch('funcs.func_one', MagicMock(return_value=0)):
result = func_two()
Where funcs.func_one is the entire module path + func name.
I have a code which has few Classes in it. Under SecondClass, there is a function called plot_image. Under this function, there are three variables defined called my_x, my_y, my_z. I am trying to make these variables accessible inside some other function called get_histogram in the same Class. Here is a non-working example in the form of a pseudo-snippet:
import some_modules_in_here #these are required for classes below
#===================================================================================================
# utility
#===================================================================================================
class FirstClass(something.something.SayClass):
def file1(self, some_arguments):
pros = do_something
return pros
#===================================================================================================
# visualize
#===================================================================================================
class SecondClass(something.something.SayClass):
def plot_image(self, some_parameter):
if some_parameter is not None:
my_x = some_value1
my_y = some_value2
my_z = some_value3
def get_histogram(self, some_parameter, some_other_parameter, return_info):
if '3d' in some_parameter:
do_this
else:
do_that
if some_other_parameter:
calculate_something
if return_info:
for k, l, m in zip(my_x, my_y, my_z):
do_some_stuff
print(something_in_here)
return_value = do_something_else_in_here
return return_value
.
.
.
def print_values(self):
'''
write some values of image to file.
'''
Second = SecondClass()
I tried the keyword global at the top of the function plot_image but that doesn't do the job for me giving error message:
"NameError: Name 'my_x' is not defined."
What is the solution?
Like ruby, how to pass code block and get it executed (yield) where you pass it. I am trying to achieve same thing in python 3.5
This is what my pseudo code looks like. How to achieve what I am trying to do. What changes would I have to make?
# Calculate all
# I want this function should yield whatever method passed to it
# THIS MUST BE A CLASS
class Calculator:
def __init__(self):
self.prefix = "hello"
def calculate(self, function_name)
local_val = 10
print("executing {} function with {}".format(function_name, self.prefix))
result = function_name(local_val)
print(result)
return result
# I want to pass these functions to Calculator().calculate() method
def add_one(x):
return x+1
def minus_one(x):
return x-1
def divide_in_half(x):
return x/2
Calculator().calculate(add_one(?))
# expect this to print:
# executing add_one function with hello
# 11
Calculator().calculate(minus_one(?))
# expect this to print:
# executing minus_one function with hello
# 9
Calculator().calculate(divide_in_half(?))
# expect this to print:
# executing divide_in_half function with hello
# 5
Functions are objects in Python, so you can just do this:
Calculator().calculate(add_one)
Calculator().calculate(minus_one)
Calculator().calculate(divide_in_half)
Note that this passes the function itself and not the name of the function. (In your code, you would have to access function_name.func_name to obtain the function's name, so I would suggest renaming function_name to fn, which is short for "function.")
You don't even need to declare predefined functions. You can use the lambda syntax to pass an anonymous callable on the fly:
# Instead of add_one, for example:
Calculator().calculate(lambda x: x + 1)
Initially, fix your __init__ so it doesn't complain when called with no args:
def __init__(self, prefix="hello")
use the function __name__ in the call to format done in calculate:
msg = "executing {} function with {}"
print(msg.format(function_name.__name__, self.prefix))
then pass the function objects along:
Calculator().calculate(add_one)
# expect this to print:
# executing add_one function with hello
# 11
Calculator().calculate(minus_one)
# expect this to print:
# executing minus_one function with hello
# 9
Calculator().calculate(divide_in_half)
# expect this to print:
# executing divide_in_half function with hello
# 5
I'm working with a code that have this appearence:
module.py:
def attribute3():
return "something3"
def attribute2():
return "something2"
def attribute1():
return "something1"
main.py:
from module import attribute1, attribute2, attribute3
def main():
return {
"attribute1": attribute1(),
"attribute2": attribute2(),
"attribute3": attribute3()
}
print main()
And i would like to know if there is any better way to create the dictionary in the main function, without the necessaty of doing "attribute: function()". I'm feeling like i'm repeating my self.
I don't have access to the module.py code, so i can't change to a Class.
I'm using Python 2.5 because this is a legacy software.
Thanks.
You could use getattr and call the arbitrary functions returned.
import some_module
def create_dict(module, names):
resp = {}
for name in names: # Iterate over an arbitrary number of arguments
# Get the function with the name provided and call it,
# setting the response as the value for the name
resp[name] = getattr(module, name)()
return resp
print create_dict(some_module, ['attribute1', 'attribute2', 'attribute3'])
I didn't test this on Python 2.5 but I don't see any reason why it wouldn't work.