testing a method with two input() in console app - python-3.x

My console app is simply adding two numbers:
def add():
a=int(input('Enter first number '))
b= int(input('Enter second number '))
return a + b
how do I unit test the above method? I tried the following but I can't seem to pass two values to it:
import unittest
from unittest.mock import patch
#patch('builtins.input', return_value='2')
#patch('builtins.input', return_value='3')
def test_add(self, a, b ):
self.assertEqual(result, 5)
While I don't get the prompts asking for numbers during testing, the tests are failing because both a and b are 2.

The side_effect parameter can be used to construct a mock object that returns different values each time it is called. Pass it a list or other iterable containing each of your return values.
You can set this attribute directly,
import unittest
from unittest.mock import patch
def add():
a=int(input('Enter first number '))
b= int(input('Enter second number '))
return a + b
class Tester(unittest.TestCase):
#patch('builtins.input')
def test_add(self, input_mock):
input_mock.side_effect = [2,3]
result = add()
self.assertEqual(result, 5)
if __name__ == '__main__':
unittest.main()
Or specify it in the decorator.
import unittest
from unittest.mock import patch
def add():
a=int(input('Enter first number '))
b= int(input('Enter second number '))
return a + b
class Tester(unittest.TestCase):
#patch('builtins.input', side_effect=[2,3])
def test_add(self, input_mock):
result = add()
self.assertEqual(result, 5)
if __name__ == '__main__':
unittest.main()

Related

Assert whether a function is being called inside another function

I have 2 functions and the other one is called only when the parameter passed is True.
def func1(para1 = True):
// Some lines of code
if para1 == True:
func2()
def func2():
// Some lines of code
Now, I'm trying to create a unittest that checks whether the nested function func2 is being called(When parameter passed to func1 is true). I checked online and found something related to Mock() but did not understand how to use for this particular test case. How can I proceed with this?
example.py:
def func1(para1=True):
if para1 == True:
func2()
def func2():
pass
test_example.py:
from unittest import TestCase
import unittest
from unittest.mock import patch
from example import func1
class TestExample(TestCase):
#patch('example.func2')
def test_func1__should_call_func2(self, mock_func2):
func1()
mock_func2.assert_called_once()
#patch('example.func2')
def test_func1__should_not_call_func2(self, mock_func2):
func1(False)
mock_func2.assert_not_called()
if __name__ == '__main__':
unittest.main()
Test result:
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK

how to write a unittest for a class?

class Hand:
def __init__(self,cards, total, soft_ace_count):
self.cards = cards
self.total = total
self.soft_ace_count = soft_ace_count
def __str__(self):
return(str(self.cards)+','+str(self.total)+','+str(self.soft_ace_count))
def add_card(self):
self.cards.append(get_card())
self.score()
def is_blackjack(self):
return len(self.cards)==2 and self.total==21
def is_bust(self):
return self.total > 21
def score(self):
self.total=0
self.soft_ace_count=0
for x in self.cards:
if x > 10:
x=10
self.total+=x
#the following code will decide 1 =11 or 1 = 1
if self.total <= 11 and 1 in self.cards:
self.total+=10
self.soft_ace_count+=1
I am trying to write the unittest for this 'Hand' class. Do I need a init setup for this particular unittest?
Here is part of code of my unittest. Thank you so much if anyone could help me with this. I just started in python. Any suggestions would help. Thank you. Neglect the indent
class hand(unittest.TestCase):
def __init__(self):
self.cards=cards
self.total = total
self.soft_ace_count = soft_ace_count
Assuming that you have your class in a module named hand.py, you can place your unittest script in the same directory. It could look like this:
import unittest
from hand import Hand
class hand(unittest.TestCase):
def test_init(self):
cards = []
h = Hand(cards, 0, 0)
self.assertEqual(h.total, 0)
self.assertEqual(h.soft_ace_count, 0)
self.assertEqual(len(h.cards), 0)
# def test_blackjack(self):
#....
# def test_score(self):
#....
# def test_OTHERTHINGS(self):
#.....
if __name__ == '__main__':
unittest.main()
if you name your unittestscript for example unittesthand.py, you can run it via "python unittestscript.py". You will get the following result:
> .
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
The unittest component has executed all methods starting with "test" and executed. In the example the "test_init" method. This is NOT the initialization of the test, but the unittest for the initialization of class Hand.
Now change for example the code to "self.assertEqual(h.total, 1)", and you will see that the unittest component reports an error.
Now you can create additional cases for the other methods.You can also create a base test case with code that is always executed before and after the unittests and so on...

Mocking Module methods

I have a situation which i could not find on stack-overflow:
some_module.py:
class SomeModule():
def a(): pass
def b(): pass
def c(): pass
#classmethod
def bring_them_altogether(cls):
cls.a()
cls.b()
cls.c()
I am writing a unittest and would like to test the method bring_them_altogether() by determining that methods a(), b() & c() are all called once.
In my testcase i have this:
test.py:
#patch('<...>.some_module.SomeModule', autospec=True)
def test_bring_them_altogether(self, mock_class):
mock_class.bring_them_altogether()
self.assertTrue(mock_class.called) # Returns me False
I want to know how to write a proper test case for bring_them_altogether() as i seem to be having some issues getting the output i want.
On that note, I want to know how to determine that a mocked-method has been called X - number of times.
Thank you for pointing me in the right direction
You should use patch.object to patch a, b, c methods of SomeModule class. Check if they are called or not after executing the bring_them_altogether method.
E.g.
some_module.py:
class SomeModule():
def a(): pass
def b(): pass
def c(): pass
#classmethod
def bring_them_altogether(cls):
cls.a()
cls.b()
cls.c()
test_some_module.py:
import unittest
from unittest.mock import patch
from some_module import SomeModule
class TestSomeModule(unittest.TestCase):
#patch.object(SomeModule, 'c')
#patch.object(SomeModule, 'b')
#patch.object(SomeModule, 'a')
def test_bring_them_altogether(self, mock_a, mock_b, mock_c):
SomeModule.bring_them_altogether()
mock_a.assert_called_once()
mock_b.assert_called_once()
mock_c.assert_called_once()
if __name__ == '__main__':
unittest.main()
unit test result with coverage report:
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Name Stmts Miss Cover Missing
------------------------------------------------------------------------------
src/stackoverflow/58950420/some_module.py 8 0 100%
src/stackoverflow/58950420/test_some_module.py 13 0 100%
------------------------------------------------------------------------------
TOTAL 21 0 100%

unit test in python for function that has no return value

I have a function that should pick only top 10 requests from list of requests:
def prioritize_top_10_requests(list_of_requests):
if not list_of_requests:
system.exit(1)
else:
for i in list_of_requests[0:10]:
print i
I want to write a unit test for this function just to check if 'i' is printed 10 times only though we have more list of requests.
I am writing python unit test cases for the first time.
I don't have python3 set up. The below code works with Python 3.
What it does is the following.
Created a UnitTest TestCase with one test, "test_priority".
In the test, redirect the stdout to a string.
Then execute the function.
Collect the print results from the string.
Remove None and empty strings and find the length.
Check if it is equal to 10.
import unittest
from io import StringIO
import sys
def prioritize_top_10_requests(list_of_requests):
for i in list_of_requests[0:10]:
print(i)
class TestMyCode(unittest.TestCase):
def test_priority(self):
sys.stdout = result = StringIO()
prioritize_top_10_requests(range(100))
sys.stdout = sys.__stdout__
printed_lines = result.getvalue()
print_count = len(printed_lines.strip().split('\n'))
self.assertEqual(print_count, 10)
if __name__ == '__main__':
unittest.main()

How do i make a unittest ? what does it look like?

def abn_abc(voteslist):
sums = {}
for vote in votes:
if vote in sums:
sums[vote] += 1
else:
sums[vote] = 1
return tally_ballots(sums)
How do I write a unit test for this function?
Something like this:
import unittest
from wherever import abn_abc
class AbnAbcTest(unittest.TestCase):
def test_abn_abc(self):
list_for_testing with = [<insert list here>]
self.assertEqual(abn_abc(list_for_testing_with), <expected result>)
if __name__ == '__main__':
unittest.main()
Here's the documentation.

Resources