How to test a function with input call?
You should probably mock the built-in input
function, you can use the teardown
functionality provided by pytest
to revert back to the original input
function after each test.
import module # The module which contains the call to input
class TestClass:
def test_function_1(self):
# Override the Python built-in input method
module.input = lambda: 'some_input'
# Call the function you would like to test (which uses input)
output = module.function()
assert output == 'expected_output'
def test_function_2(self):
module.input = lambda: 'some_other_input'
output = module.function()
assert output == 'another_expected_output'
def teardown_method(self, method):
# This method is being called after each test case, and it will revert input back to original function
module.input = input
A more elegant solution would be to use the mock
module together with a with statement
. This way you don't need to use teardown and the patched method will only live within the with
scope.import mock
import module
def test_function():
with mock.patch.object(__builtins__, 'input', lambda: 'some_input'):
assert module.function() == 'expected_output'
Pytest: How to test a separate function with input call?
Your problem has nothing to do with moving the input
to a separate function, or even with monkeypatching; it has to do with passing the wrong number of arguments—just as the error message says.
In the example you refer to, the monkeypatching function is defined to take one parameter, and the input
call passes one argument.
If your own attempt, the monkeypatching function is defined to take one parameter, but the input
call passes no arguments.
You can just define it to take an optional parameter, just like the real input:
m.setattr('builtins.input', lambda prompt="": ans)
How to test Input with React Testing Library?
Your tested component is a controlled component : it receives (props) its value from the parent component, with a function reference which notifies the parent that the user changed the input value. Typically this function will update the parent state, which is passed down to the child component, and used as the input value.
In your test you only render the child component, and you mock the callback function. So you cannot expect the input value to change when triggering user interactions in your test. You can only test that the title
props is used as value for the input, and that the callback function (which is mocked in your test) is correctly called when you trigger user interactions. But you cannot test a "full scenario" without rendering the parent component.
test("input value is the title props", async () => {
renderComponent("test");
const input = await screen.findByRole("textbox", { name: /search/i });
await waitFor(() => expect(input).toHaveValue("test"));
});
test("callback function is called on user interactions", async () => {
renderComponent("test");
const input = await screen.findByRole("textbox", { name: /search/i });
userEvent.type(input, "new value");
expect(mockedOnChange).toHaveBeenCalledWith("new value");
});
How to test function, that has two or more input()'s inside?
Here is my solution:
class SimulatedInput:
def __init__(self,*args):
self.args = iter(args)
def __call__(self,x):
try:
return next(self.args)
except StopIteration:
raise Exception("No more input")
Then you could use it like you did before:def test_some_function(self):
codefile.input = SimulatedInput("u","v")
codefile.some_function() . . . .
How to test interactive python script with multiple `input` functions
You can use side_effect
for this. Side_effect takes a list as input and provides you the result in the order of elements.
Assuming you have the test and source code in separate directories
@patch('sample.input')
def test_options(mock_input):
mock_input.side_effect = ['y', 'y']
result = unsubscribe()
assert result == "your discount code is SAVE20, and we are glad you have you back"
You can take this to the next step by defining the exact output you want for your use case, instead of arbitrarily passing yes and no values@patch('sample.input')
def test_options(mock_input):
def input_side_effect(*args, **kwargs):
m = {
'are you unsubscribing? [y/n]': 'y',
'would you like a 20%% off discount code? [y/n]': 'y',
}.get(args[0])
if m:
return m
pytest.fail('This question is not expected')
mock_input.side_effect = input_side_effect
result = unsubscribe()
assert result == "your discount code is SAVE20, and we are glad you have you back"
Related Topics
Filename and Line Number of Python Script
Setting Up S3 for Logs in Airflow
Python 'Requests' Library - Define Specific Dns
Difference Between Variable and Get_Variable in Tensorflow
Importerror: Cannot Import Name Numpy_Mkl
Matplotlib Custom Marker/Symbol
Python, Default Keyword Arguments After Variable Length Positional Arguments
How to Concatenate Three Excels Files Xlsx Using Python
How to Delete Created Variables, Functions, etc from the Memory of the Interpreter
Numpy Argsort - What Is It Doing
Pandas Number Rows Within Group in Increasing Order
Is There a Builtin Identity Function in Python
Why Is True Returned When Checking If an Empty String Is in Another
Download Image File from the HTML Page Source
Converting Strings to Floats in a Dataframe